123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980 |
- #!/usr/bin/env python
- #! coding: utf-8
- #! python3
- # Kazeged engine main file
- # Dirty as hay, if you learn python with this file, you may learn garbage/bad practices.
- # 2022-2024
- import sys
- import random
- import os
- from engine.GM import *
- enginePath = None
- if getattr( sys, 'frozen', False ) :
- enginePath = os.path.join( os.path.dirname( sys.executable ), "engine" )
- elif __file__:
- enginePath = os.path.dirname( __file__ )
- engineFont = None
- def init() :
- global engineFont
- global enginePath
- game_init()
-
- #enginePath = os.path.dirname( os.path.realpath( __file__ ) )
- fontPath = os.path.join( enginePath, "aesymatt.ttf" )
- engineFont = font_add( fontPath, 20 )
-
- #==============================================================================
- # Engine intro
- #==============================================================================
- def intro() :
- global engineFont
- init()
-
- draw_set_color( (255,255,255) )
- draw_set_halign( fa_center )
- draw_set_valign( fa_middle )
-
- running = True
- counter = 0
- step = 0
-
- titleFont = font_add( None, 64 )
- titleText = "Kazeged"
-
- subText = random.choice( ["Stories to tell", "The mane engine", "Always mare", "Horsing around"] )
-
-
- W,H = surface_get_target().get_size()
-
- while running:
-
- # Event handling, gets all event from the event queue
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- running = False
-
-
- # Step
- counter += 1
- if step == 0 :
- C = 192 * min( 1, (counter/63.0) )
- if counter > 63 :
- counter = 0
- step = 1
-
- elif step == 1:
- C = 192
- if counter > 63 :
- counter = 0
- step = 2
-
- elif step == 2:
- C = 192 * (1-min( 1, (counter/31.0) ))
- if counter > 31 :
- running = False
- else :
- C = 255
-
- # Draw
- draw_clear()
-
- r = random.randrange(-2,2)
- y = (H/2)-16
- draw_set_font( titleFont )
- draw_text_color( ((W/2)+2+r, y+2+r), titleText, (C,0,0) )
- draw_text_color( ((W/2)-2+r, y+2+r), titleText, (0,C,0) )
- draw_text_color( ((W/2)+r, y-2+r), titleText, (0,0,C) )
- draw_text_color( (W/2, y), titleText, (0,0,0) )
-
- draw_set_font( engineFont )
- draw_text_color( (W/2, y+48), subText, (C,C,C) )
-
- # surface.fill( blendColor, None, 0x3 ) #0x3 = BLEND_RGB_MULT
-
- pygame.display.flip()
- GM.game_clock.tick(60)
- pygame.event.poll()
-
- # Reset text atributes to default
- draw_set_color( c_white )
- draw_set_halign( fa_left )
- draw_set_valign( fa_top )
-
- #==============================================================================
- # Displays a list of game
- #
- # Returns the game path, None if none choosen
- #==============================================================================
- def game_selection( gameLibFolder="" ) :
- init()
-
- selectedGamePath = None
- selectedGameIndex = 0
-
- # Default font
- #engineFont = font_add( "engine/aesymatt.ttf", 20 )
-
- # Default icon
- defaultIcon = background_add( "__game_selection_defaultIcon__", "engine/icon - small.png" )
-
- # Background music
- musicPlaying = False
- musicFile = "engine/8bit Bossa - compressed.mp3"
- if os.path.exists( musicFile ) :
- pygame.mixer.music.load( musicFile )
- pygame.mixer.music.play( loops=-1 )
- musicPlaying = True
- else:
- warning( "Background music not found" )
-
- # Configure display
- pygame.display.set_caption( "Game selector - Kazeged" )
- draw_set_color( (0xff,0x99,0x33) )
- draw_set_halign( fa_left )
- draw_set_valign( fa_top )
- draw_set_font( engineFont )
-
- # Scan games
- info( "Loading game list..." )
- pygame.display.flip()
- gameList = []
-
- # default folder
- if os.path.exists( "game" ) :
- path = "game"
- configFile = os.path.join( path, "read me.txt" )
- if os.path.exists( configFile ) :
- print( "Default game " )
- name = "default game"
- icon = background_add( "__game_selection_defaultGameIcon__", os.path.join( path, "icon.png" ) )
- if icon == None : icon = defaultIcon
- gameList.append( {"name":name, "path":path, "icon":icon} )
-
- # from game lib
- if os.path.exists( gameLibFolder ) :
-
- _, directories, files = next( os.walk( gameLibFolder ) )
-
-
- # Check wich folder is a game
- for directory in directories :
- configFile = os.path.join( gameLibFolder,directory, "read me.txt" )
- if os.path.exists( configFile ) :
- print( "Game: "+directory )
- path = os.path.join( gameLibFolder,directory )
- name = directory
- icon = background_add( f"__game_selection_{name}GameIcon__", os.path.join( path, "icon.png" ) )
- if icon == None : icon = defaultIcon
- gameList.append( {"name":name, "path":path, "icon":icon} )
-
-
- else :
- warning( "game lib folder does not exists." )
-
-
- if len( gameList ) == 0 :
- warning( "No game found." )
-
- displayTop = 40
- lineHeight = 40
-
- running = True
- while running:
-
- # Event handling, gets all event from the event queue
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- running = False
-
- if event.type == pygame.MOUSEBUTTONDOWN:
- if (selectedGameIndex >= 0) and (selectedGameIndex < len(gameList)) :
- selectedGamePath = gameList[ selectedGameIndex ]["path"]
- running = False
-
- # Get the highlighted game (if any)
- mouse_x, mouse_y = pygame.mouse.get_pos()
-
- if mouse_y > displayTop :
- selectedGameIndex = int( (mouse_y-displayTop) / lineHeight)
- else:
- selectedGameIndex = -1
-
- # Displays the games found
- draw_clear( (0x47,0x33,0x1f) )
- draw_set_valign( fa_top )
- draw_text( (4,4), "Select a game" )
- draw_set_valign( fa_middle )
-
- currentIndex = 0
- for game in gameList :
-
- Y = displayTop+(lineHeight*currentIndex)
-
- if currentIndex == selectedGameIndex :
- draw_set_color( (139,101,29) )
- draw_rectangle( (1,Y+1), (638,Y+lineHeight-1), outline=False )
- draw_set_color( (0xff,0x99,0x33) )
- draw_rectangle( (1,Y+1), (638,Y+lineHeight-1), outline=True )
-
- draw_set_color( (0xff,0x99,0x33) )
- draw_text( (40,Y+20), game["name"] )
-
- if game["icon"] != None :
- draw_background( game["icon"], 4, Y+4 )
-
- currentIndex += 1
-
-
- pygame.display.flip()
- GM.game_clock.tick(60)
-
- # Stop the music
- if musicPlaying :
- pygame.mixer.music.stop()
- pygame.mixer.music.unload()
-
- # Reset text atributes to default
- draw_set_color( c_white )
- draw_set_halign( fa_left )
- draw_set_valign( fa_top )
-
- return selectedGamePath
- #==============================================================================
- # Reads a Kazeged file
- #==============================================================================
- def read_kazeged_file( kazegedFile=None ) :
- data = None
-
- if os.path.exists( kazegedFile ):
- data = []
-
- # Reads the file line by line
- with open( kazegedFile, "r" ) as file:
- RAWData = file.readlines()
-
- # Treat and arrange the data in an easier to treat format
- currentLine = 1
- for line in RAWData:
-
- # Remove end of line and trailing spaces
- line = line.strip()
-
- # if the line is not empty, let's treat it
- if len(line) >= 1 :
-
- # if the line is not a comment
- if line.strip()[0] != "#" :
-
- # Slash the spaces
- items = line.split( " " )
-
- # Find if any quote surrounded string have been severed during slashing
- #TODO rewrite this whole mess...
- stringStarted = False
- startIndex = 0
- currentIndex = 0
- toPop = []
- for blob in items:
-
- # If the blob is surrounded by quotes try to fix things
- if len( blob ) > 1 :
- if (blob[0] == '"') and (blob[-1] == '"') :
- if stringStarted :
- error( f"line {currentLine} malformed! token {blob} ({line[0:12]}...)" )
- break
- else:
- info( f"line {currentLine}. token {blob} don't need quotes ({line[0:12]}...)" )
- items[currentIndex] = items[currentIndex][1:-1]
-
- # Is start of a string reached?
- #TODO this mess don't recognize things like " string", "string " or " string " because the quote is conidered a blob
- if len( blob ) > 0 :
- if (blob[0] == '"') :
- stringStarted = True
- startIndex = currentIndex
- else:
- if stringStarted == True :
- if blob[-1] == '"':
- text = ' '.join( items[startIndex:currentIndex+1] )[1:-1]
- items[startIndex] = text
-
- # Add indexes to pop latest first to, well, keep the index meaning something
- toPop.insert( 0, [(startIndex+1), (currentIndex-startIndex)] )
-
- stringStarted = False
- else:
- pass
- else:
- pass
-
- #Is it a blank/empty item not part of a string?
- if not stringStarted :
- if blob in ['', ' ', '\t'] :
- toPop.insert( 0, [currentIndex,1] )
-
- currentIndex += 1
-
- # Pop the unwanted items
- # The list should start by the last idexes, so we can pop them out
- for index in toPop:
- for i in range(index[1]):
- items.pop( index[0] )
-
- # Add our fresh items to the data gathered
- data.append( items )
- else:
- #print( "Comment: "+line[1:] )
- pass
-
- currentLine += 1
-
- else:
- error( f"can't find file {kazegedFile}" )
-
- return data
- class text_engine:
- font = None
- position = (0,0)
- size = (512,64)
- lines = (2,32)
- color = (0,0,0)
- backgroundColor = (255,255,255,128)
- scrollSpeed = 1
- scrollCpt = -1
-
- def set_font( self, font=None ):
- self.font = font
-
- def set_position( self, position=(0,0) ):
- self.position = position
-
- def set_size( self, size=(512,64) ):
- self.size = size
-
- def set_lines( self, lines=(2,32) ):
- self.lines = lines
-
- def set_color( self, color=(0,0,0) ):
- self.color = color
-
- def set_background_color( self, backgroundColor=(255,255,192,192) ):
- self.backgroundColor = backgroundColor
-
- def set_scroll_speed( self, scrollSpeed=2 ) :
- self.scrollSpeed = scrollSpeed
-
-
- # if -1, scroll from start, else, int represent the number of chars left to draw
- # ( so 0 is static full drawn text)
- def reset_scrolling( self, forceValue=-1 ) :
- self.scrollCpt = forceValue
-
- def draw_text( self, text=["Yay!"], forceStatic=False ) :
-
- if isinstance( text, list ) :
- if len( text ) > 0 :
- top = self.position
- size = self.size
-
- # draw_set_alpha( 179/255 )
- draw_set_color( self.backgroundColor )
- draw_rectangle( top, (top[0]+size[0],top[1]+size[1]), outline=False )
-
- # draw_set_alpha( 1 )
- draw_set_color( self.color )
- txty = 12-3 # Pixel perfecet is 12, 3 is because of the font
-
- # Curate/sanitize text
- curatedText = []
- for line in text :
- if isinstance( line, str ) :
- curatedText.append( line.strip() )
-
- # Manage scrolling
-
- totalNbChars = 0
- for line in curatedText :
- totalNbChars += len( line )
-
- if self.scrollCpt == -1 :
- self.scrollCpt = totalNbChars
-
- draw_set_font( self.font )
-
- alreadyDrawnChars = 0
- for line in curatedText :
-
- if alreadyDrawnChars < (totalNbChars-self.scrollCpt) :
- xoffset = 4 + (8*(31-len(line)))
- charToDraw = (totalNbChars-self.scrollCpt)-alreadyDrawnChars
- draw_text( (top[0]+xoffset,top[1]+txty), line[:charToDraw] )
- txty+=self.lines[1]
- alreadyDrawnChars += len(line)
-
- # Manage scrolling
- if self.scrollCpt > 0 :
- self.scrollCpt -= self.scrollSpeed
- if self.scrollCpt < 0 :
- self.scrollCpt = 0
-
- draw_set_color( c_white )
- else :
- warning( "draw text called, but no text" )
- else:
- warning( "draw text called, but argument is not a list" )
-
- return self.scrollCpt
- #==============================================================================
- # A Kazeged game
- #==============================================================================
- class obj_game:
- """---"""
- name = "Unamed game"
- resolution = (320,240)
- saveEnabled = False
- basePath = None
- firstScene = None
- mainMenu = ["Quit"]
- options = None
- scene = None
- text = None
-
- time = 0
- timeSteps = ( "day", "night" )
-
- # Backgrounds
- backgrounds = []
-
- #
- def __init__( self, basePath=None ):
- # init()
- self.basePath = basePath
- self.text = text_engine()
- self.load_configuration()
-
- def load_configuration( self ):
-
- # Load the config file
- data = read_kazeged_file( os.path.join( self.basePath, "configuration/game.txt" ) )
- if data == None :
- error( "No config File!" )
- exit( 1 )
-
- # Apply config
- for blob in data :
-
- token = blob[0]
- nbArgs = len( blob )
-
- # TODO Use a selection if porting to python 3.10
- if token == "Name":
- if nbArgs > 1 :
- self.name = blob[1]
- else :
- warning( "configuration: 'Name' empty" )
-
- elif token == "Title":
- if nbArgs > 1 : file = os.path.join( self.basePath, "configuration", blob[1] )
- background_add( "__main_menu_background__", file )
-
- elif token == "Size":
- if nbArgs >= 3 :
- self.resolution = ( int(blob[1]), int(blob[2]) )
-
- window_set( self.resolution, flags=pygame.RESIZABLE|pygame.SCALED|pygame.SHOWN )
- # pygame.display.toggle_fullscreen()
- else :
- warning( "configuration: 'Size' don't have enough parameters. Skipped." )
-
- elif token == "Save":
- if blob[1] == "ON" :
- self.saveEnabled = True
- else :
- self.saveEnabled = False
-
- elif token == "Time":
- self.time = 0
- self.timeSteps = blob[1:]
-
- elif token == "Font":
- self.textFont = font_add( os.path.join( self.basePath, "configuration", blob[1] ), blob[2] )
- self.text.set_font( self.textFont )
- draw_set_font( self.textFont )
-
- elif token == "Music":
- fileA = None
- fileB = None
- if nbArgs > 1 : fileA = os.path.join( self.basePath, "configuration", blob[1] )
- if nbArgs > 2 : fileB = os.path.join( self.basePath, "configuration", blob[2] )
-
- if fileA != None :
- # Simple music, no intro part
- if fileB == None :
- music_add( "__main_menu_music__", fileA )
-
- # Else, music with intro
- else :
- music_add( "__main_menu_music__", fileB, fileA )
-
- elif token == "Start":
- if nbArgs > 1 :
- self.firstScene = blob[1]
- else :
- warning( "configuration: starting scene is empty" )
-
- # Option name [defaultValue [description]]
- elif token == "Option":
- if self.options == None : self.options = {}
- oName = None
- oVals = {"value":0, "description":None}
- if nbArgs > 1 : oName = blob[1]
- if nbArgs > 2 : oVals["value"] = blob[2]
- if nbArgs > 3 : oVals["description"] = blob[3]
-
- if oVals["description"] == None : oVals["description"] = oName
- if oName != None :
- if oName not in self.options :
- self.options[oName] = oVals
- else :
- warning( f"configuration: option '{oName}' already defined. Keeping the first one." )
-
- elif token == "TextPosition" :
- if nbArgs >= 3 :
- self.text.set_position( (int(blob[1]), int(blob[2])) )
- else:
- warning( "configuration: 'TextPosition' don't have enough parameters. Skipping." )
-
- elif token == "TextSize" :
- if nbArgs >= 3 :
- self.text.set_size( (int(blob[1]), int(blob[2])) )
- else:
- warning( "configuration: 'TextSize' don't have enough parameters. Skipping." )
-
- elif token == "TextLines" :
- if nbArgs >= 3 :
- self.text.set_lines( (int(blob[1]), int(blob[2])) )
- else:
- warning( "configuration: 'TextLines' don't have enough parameters. Skipping." )
-
- elif token == "TextColor" :
- if nbArgs >= 2 :
- self.text.set_color( sanitize_color(blob[1]) )
- else:
- warning( "configuration: 'TextColor' don't have enough parameters. Skipping." )
-
- elif token == "TextBackgroundColor" :
- if nbArgs >= 2 :
- self.text.set_background_color( sanitize_color(blob[1]) )
- else:
- warning( "configuration: 'TextBackgroundColor' don't have enough parameters. Skipping." )
-
- elif token=="TextScrollSpeed" :
- if nbArgs >= 2 :
- self.text.set_scroll_speed( float(blob[1]) )
- else:
- warning( "configuration: 'TextScrollSpeed' don't have enough parameters. Skipping." )
-
- else :
- warning( f"configuration: token '{token}' unknown." )
-
-
- if self.name != None :
- pygame.display.set_caption( f"{self.name} - Kazeged" )
-
- self.mainMenu = []
- if self.firstScene == None :
- error( "configuration: No starting scene set!" )
- else :
- self.mainMenu.append( "Play" )
-
- if self.saveEnabled : self.mainMenu.append( "Load" )
- if self.options != None : self.mainMenu.append( "Options" )
- self.mainMenu.append( "Quit" )
-
-
- #----------------------------------------
- # Load a scene
- def scene_load( self, sceneName=None ) :
-
- # First, cleanup
- self.scene_unload()
-
- # Then, try to load the new scene
- # It's so clunky and fat and not optimized... sorry...
- if sceneName != None :
-
- scenePath = os.path.join( self.basePath, "scenes", sceneName, "descriptor.txt")
- if os.path.exists( scenePath ) :
- info( f"Loading scene '{sceneName}'..." )
- self.scene = {
- "name":sceneName,
- "ressources":{
- "actors":[],
- "backgrounds":[],
- "musics":[],
- "sounds":[],
- },
- "actions":[]
- }
-
- data = read_kazeged_file( scenePath )
-
- # Parse the data
- for line in data :
- print( line )
- # ("Music", "Background", "Character", "Fadein", "Message")
- if line[0] == "Kazeged" :
- # info( "Cheers m8! ^:)" )
- pass
-
- elif line[0] == "Actor" :
- file = line[1]
- name = ''.join(os.path.splitext(os.path.basename(line[1]))[:-1])
- if not background_exists( name ) :
- path = self.search_ressource( file, "actors", sceneName )
- if path != None :
- # Suceeded in loading the resource?
- if background_add( name, path ) == name :
- self.scene["ressources"]["actors"].append( name )
- actor = {"kind":"Actor", "name":name}
- if "COORDS" in line :
- print( "COORDS!!!1!" )
- self.scene["actions"].append( actor )
-
- elif line[0] == "Background" :
- file = line[1]
- name = ''.join(os.path.splitext(os.path.basename(line[1]))[:-1])
- if not background_exists( name ) :
- path = self.search_ressource( file, "backgrounds", sceneName )
- if path != None :
- # Suceeded in loading the resource?
- if background_add( name, path ) == name :
- self.scene["ressources"]["backgrounds"].append( name )
- self.scene["actions"].append( {"kind":"Background", "name":name} )
-
- elif line[0] == "Message" :
- if len(line) > 1 :
- self.scene["actions"].append( {"kind":"Message", "lines":line[1:]} )
-
- elif line[0] == "Music" :
- file = line[1]
- name = ''.join(os.path.splitext(os.path.basename(line[1]))[:-1])
- if not music_exists( name ) :
- path = self.search_ressource( file, "musics", sceneName )
- if path != None :
- # Suceeded in loading the resource?
- if music_add( name, path, intro=None ) == name :
- self.scene["ressources"]["musics"].append( name )
- self.scene["actions"].append( {"kind":"Music", "name":name} )
-
-
- else :
- error( f"scene loader: can't find scene '{scenePath}'" )
- else :
- error( "scene loader: scene is 'None'" )
-
- print( self.scene )
-
- #----------------------------------------
- # Unload the ressources loaded by the previous scene
- def scene_unload( self ) :
- print( self.scene )
-
- if self.scene != None :
- if "ressources" in self.scene :
- deleters = {
- "actors":background_delete,
- "backgrounds":background_delete,
- "musics":music_delete,
- "sounds":sound_delete
- }
- for reskind in self.scene["ressources"] :
- for res in self.scene["ressources"][reskind] :
- print( f"delete {reskind} {res}" )
- deleters[reskind]( res )
-
- self.scene = {}
- print( self.scene )
-
-
- #----------------------------------------
- # Look for a ressource in the game folder
- def search_ressource( self, name=None, sharedFolder=None, sceneName=None) :
- path = None
- if name != None :
- path = os.path.join( self.basePath, sharedFolder, name )
- if not os.path.exists( path ) :
- path = os.path.join( self.basePath, "scenes", sceneName, name )
- if not os.path.exists( path ) :
- path = None
- print( f" {path}" )
-
- return path
-
- #----------------------------------------
- # Main menu
- def main_menu( self ) :
-
- background_color = c_black
- draw_set_font( self.textFont )
-
- # Create a surface on screen
- screen = surface_get_target()
- display = pygame.Surface( self.resolution )
-
- music_play( "__main_menu_music__", loop=True )
-
- # Variable to control the main loop
- running = True
- click = False
- state = "main menu"
-
- displayTop = (self.resolution[1]/2)
- lineHeight = 24
-
- # main loop
- while running:
-
- # Event handling, gets all event from the event queue
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- running = False
-
- if event.type == pygame.MOUSEBUTTONDOWN:
- click = True
-
- # Draw
- draw_clear( background_color )
- draw_background( "__main_menu_background__", 0,0 )
-
- # Get the highlighted game (if any)
- mouse_x, mouse_y = pygame.mouse.get_pos()
-
- if mouse_y > displayTop :
- selectedOption = int( (mouse_y-displayTop) / lineHeight)
- else:
- selectedOption = -1
-
- # Displays options
- if state == "main menu" :
- draw_text( (4,4), self.name )
- draw_set_halign( fa_center )
- draw_set_valign( fa_middle )
-
- selected = True
- for index in range( len(self.mainMenu) ) :
- x = (self.resolution[0]/2)
- y = (self.resolution[1]/2) + (lineHeight*index)
- if index == selectedOption :
- draw_set_color( (127,101,29) )
- draw_rectangle( (0.5*x,y+1), (1.5*x,y+lineHeight-1), outline=False )
-
- draw_set_color( c_white )
- draw_text( (x,y+(0.5*lineHeight)), self.mainMenu[index] )
-
- draw_set_halign( fa_left )
- draw_set_valign( fa_top )
-
-
- if click :
- if selectedOption in range( len(self.mainMenu) ) :
- if self.mainMenu[selectedOption] == "Play" :
- # state = "run game"
- # Run the game itself (the first scene)
- pygame.mixer.music.stop()
- self.scene_load( self.firstScene )
- self.loop()
- music_stop()
- state = "main menu"
- music_play( "__main_menu_music__", loop=True )
-
- elif self.mainMenu[selectedOption] == "Load" :
- state = "save menu"
- elif self.mainMenu[selectedOption] == "Options" :
- state = "options"
- elif self.mainMenu[selectedOption] == "Quit" :
- running = False
-
- elif state == "options" :
- draw_text( (4,4), "Options" )
- if click :
- state = "main menu"
-
- elif state == "save menu" :
- draw_text( (4,4), "Save menu" )
- if click :
- state = "main menu"
-
- else :
- state == "main menu"
-
-
- # Update the display
- pygame.display.flip()
- GM.game_clock.tick(60)
- click = False
-
- return None
-
- #----------------------------------------
- # Main game loop
- def loop( self ) :
-
- background_color = c_black
- draw_set_font( self.textFont )
-
- # Create a surface on screen
- screen = surface_get_target()
- display = pygame.Surface( self.resolution )
-
- state = "game"
-
-
- # Variable to control the main loop
- running = False
- if self.scene == None :
- error( "No scene loaded. Check that the game is not corrupted." )
- state = "error"
- else :
- running = True
-
- # Init
- readNextItem = True
- currentItemIndex = 0
- current_background = None
- current_music = None
- current_character = None
- current_characterCoords = (0,0)
- current_text = None
-
- charLeft = 0
- fadeColor = (0,0,0)
- fadeTimeLeft = 0
-
- click = False
-
- # main loop
- while running:
-
- # Event handling, gets all event from the event queue
- click = False
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- running = False
-
- if event.type == pygame.MOUSEBUTTONDOWN:
- click = True
-
-
- # Scan next item in scene if needed
- if readNextItem :
-
- if currentItemIndex >= len(self.scene["actions"]) :
- running = False
- else :
- item = self.scene["actions"][currentItemIndex]
-
- # "kind":"Fadein", "duration":60, "color":(0,0,0)
- if item["kind"] == "Fadein" :
- draw_text( (4,36), "FadeIn" )
- pass
-
- # "kind":"Background", "name":"bck_name"
- if item["kind"] == "Background" :
- current_background = item["name"]
-
- # "kind":"Music", "name":"msk_name", "LOOPING":True
- elif item["kind"] == "Music" :
- music_stop()
- current_music = item["name"]
- looping = False
- if "LOOPING" in item :
- looping = True
- music_play( current_music, looping )
-
- # "kind":"Character", "name":"bck_name", "COORDS":[78,0]
- elif item["kind"] == "Actor" :
- current_character = item["name"]
- if "COORDS" in item :
- current_characterCoords = item["COORDS"]
-
- # "kind":"Message", "lines":["text", "text"]
- elif item["kind"] == "Message" :
- current_text = item["lines"]
- self.text.reset_scrolling()
- charLeft = 999
- readNextItem = False
-
- currentItemIndex += 1
-
- # Pass to the next item if we can
- if click and (readNextItem == False) :
- if charLeft == 0 :
- readNextItem = True
-
- # Draw
- if state == "error" :
- draw_clear( c_maroon )
- draw_text( (4,4), "Error, no scene loaded." )
- draw_text( (4,24), "Please check that your game files are not corrupted." )
-
- else :
- draw_clear( background_color )
- draw_background( current_background, 0,0 )
-
- draw_text( (4,4), self.scene["name"] )
-
- # Background
- draw_background( current_character, current_characterCoords[0], current_characterCoords[1] )
-
- # Text
- if current_text != None :
- if click :
- self.text.reset_scrolling( 0 )
- charLeft = self.text.draw_text( current_text )
-
-
- # Update the display
- pygame.display.flip()
- GM.game_clock.tick(60)
-
- return None
-
- #==============================================================================
- #
- #==============================================================================
- def game_start( gameFolder ) :
-
- info( f"Loading game {gameFolder}" )
-
- # Sanity check
- if gameFolder == None :
- game_end()
-
- else :
- # Initialization
- init()
-
- game = obj_game( gameFolder )
-
- # Let's play!
- game.main_menu()
-
- pass
|