123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- # THIS IS A SOURCE CODE FILE FROM I'M NOT EVEN HUMAN THE GAME.
- # IT COULD BE USED IN A DIFFERENT PIECE OF SOFTWARE ( LIKE A
- # DIFFERENT GAME ), BUT IT WAS ORIGINALLY WRITTEN FOR I'M NOT
- # EVEN HUMAN THE GAME.
- # THE DEVELOPERS OF THE GAME ARE : (C) J.Y.AMIHUD, AYYZEE AND
- # OTHER CONTRIBUTORS. THIS AND OTHER FILES IN THIS GAME,
- # UNLESS SPECIFICALLY NOTED, COULD BE USED UNDER THE TERMS OF
- # GNU GENERAL PUBLIC LICENSE VERSION 3 OR ANY LATER VERSION.
- import os
- import datetime # For the FPS meter mainly
- # GTK module ( Graphical interface
- import gi
- gi.require_version('Gtk', '3.0')
- from gi.repository import Gtk
- from gi.repository import Gdk
- import cairo
- import threading
- # Engine submodules ( Layers )
- from modules import ui
- # Game scenes ( layers )
- from modules import testing
- from modules import main_menu
- from modules import settings
- from modules import editor
- from modules import world
- from modules import gameplay
- def previous(game):
- """This function is making an exact copy of game.current
- to preserve the values from the previous frame."""
-
- game.previous = {}
- for i in game.current:
- if type(game.current[i]) == list or type(game.current[i]) is dict:
- game.previous[i] = game.current[i].copy()
- else:
- game.previous[i] = game.current[i]
- def run():
- """This function will launch the game's engine and make a
- window and everything."""
- # This is a hack. game will be a Gtk.Window() object. But I
- # am going to add into it a lot of other things and pass it
- # to all the sub-functions as a kind of container for semi-
- # global variables. Anything important goes into the game
- # variable.
-
- game = Gtk.Window()
- game.set_default_size(1200,720)
- game.set_position(Gtk.WindowPosition.CENTER)
- game.connect("destroy", Gtk.main_quit)
- game.set_default_icon_from_file("icon.png")
- game.set_title("I'm Not Even Human - The Game")
- # Catching events from keys and mouse clicks
- game.connect("button-press-event", mouse_button_press, game)
- game.connect("button-release-event", mouse_button_release, game)
- game.connect("key-press-event", key_press, game)
- game.connect("key-release-event", key_release, game)
-
- # To catch the scroll events from the mouse wheel in GTK I
- # need to have a scrolled windows widget. There is no use
- # for it. I'm making it only to add this functionality
- # which is just an another hack.
- scroll = Gtk.ScrolledWindow()
- scroll.connect("scroll-event", scrolling, game)
- game.scene = "main_menu" # Current menu of the game
- game.map = {} # Chunks of the map
-
- game.current = {} # Values for the current frame
- game.previous = {} # Values for the previous frame
- game.images = {} # All images loaded to memory
- game.menus = {} # Metada to navigate buttons using a keyboard
- game.FPS = 0 # Frames per second of the game.
- game.AFPS = 0 # Average frames per second
- game.scroll = {} # Scrolls
- settings.update_worlds(game) # Worlds metadata | game.worlds
- settings.load_settings(game) # Loading settings | game.settings
- world.update_elements(game) # Loading assets | game.elements
-
- ui.load_palete(game) # game.palete ( colors from assets/palete.json )
-
- game.current["frame"] = 0 # The number of frames from launch
- game.current["camera"] = [0,0,0] # Game camera
- game.current["testing"] = False # Whether the devmode is on / off
- game.current["LMB"] = False # Left Mouse Button
- game.current["MMB"] = False # Middle Mouse Button
- game.current["RMB"] = False # Right Mouse Button
- game.current["keys"] = [] # List of pressed keys ( IDs )
- game.current["scroll"] = [0,0]
- # The same keys can have multiple IDs depending on what type of
- # keyboard you have or where on the keyboard they are located.
- # These arrays store the IDs of common keys.
- game.current["ctrl"] = [65507, 65508] # [CTRL]
- game.current["plus"] = [61, 43, 65451] # [+]
- game.current["minus"] = [45, 95, 65453] # [-]
- ####################################################################
- # #
- # #
- # GAME CURRENT STATE OBJECT INDEXING DYNAMICS #
- # #
- # #
- ####################################################################
-
- # [Object] [Potision] [Condition]
- # game.current["state"] = {"4211D79": {"xyz":[0,0,0],
- # "colision": False,
- # "orientation":"Up"}}
- game.current["state"] = {
- "objects":[
- # Objects that are not in the map, but load anyway
-
- {
- "asset":"characters/4211D79",
- "xyz":[0,0,0],
- "velocity":[0,0,0],
- "cell":[0,0],
- "last_before_colision":[0,0,0],
- "check_mark":[0,0,0],
- "orientation":"Up",
- "grounded":False,
- "health":1.0,
- "time-falling":0}],
- # List of objects that the caracter may control
-
- "controlling":{0:True},
- # List of objects that are on the map, but which
- # became dynamic, which means they need to be
- # excluded from the map statis view.
-
- "map_exclude":[]
- }
-
-
- # Making the copy of all current, so far into previous
- previous(game)
- # Setting up the FPS meter
- game.sFPS = datetime.datetime.now()
- # Setting the drawable
- gamedraw = Gtk.DrawingArea()
- gamedraw.set_size_request(800, 600)
- scroll.set_size_request(800, 600)
- game.add(scroll)
- scroll.add_with_viewport(gamedraw)
- gamedraw.connect("draw", gamedrawing, game)
- # Running
- game.show_all()
- Gtk.main()
- def gamedrawing(gamedrawing, main_layer, game):
- """You can think of this function as one that combines various
- layers into a finished image. And handles some logic related
- to it."""
-
- # FPS counter
- game.fFPS = datetime.datetime.now()
- game.tFPS = game.fFPS - game.sFPS
- game.FPS = int ( 1.0 / ( game.tFPS.microseconds /1000000))
- if game.current["frame"] % 30 == 0:
- game.AFPS = game.FPS
- game.sFPS = datetime.datetime.now()
-
- # Updating the frame
- game.current["frame"] += 1
-
- # Getting mouse data about the frame
- game.current['mx'] = game.get_pointer()[0] / game.settings["pixels"]
- game.current['my'] = game.get_pointer()[1] / game.settings["pixels"]
- game.current['w'] = int(round(game.get_size()[0] / game.settings["pixels"] ))
- game.current['h'] = int(round(game.get_size()[1] / game.settings["pixels"] ))
- if game.current["frame"] == 1:
- previous(game)
-
-
- # Switching the fullscreen mode on and off. Ctrl-F
- # Warning! The method used to fullscreen bypasses and disobeys some window manager
- # rules.
-
- # [CTRL] [F]
- if 65507 in game.current["keys"] and 102 in game.current["keys"]:
- game.settings["fullscreen"] = not game.settings["fullscreen"]
- game.current["keys"].remove(102)
- if game.settings["fullscreen"]:
- game.fullscreen()
- else:
- game.unfullscreen()
- layers = [] # Layers to draw
- if game.scene == "main_menu":
- layers.append(main_menu.layer(game))
- elif game.scene == "settings":
- layers.append(settings.layer(game))
- elif game.scene == "editor":
- layers.append(editor.layer(game))
- elif game.scene == "gameplay":
- layers.append(gameplay.layer(game))
-
- # Check if any of the keys are currently being pressed by comparing them
- # to the ones that are present in their respective arrays.
- # [KEYS] [ARRAY that has the common key IDs] [ARRAY that has ALL of the key IDs]
- game.current["ctrlDown"] = any(item in game.current["ctrl"] for item in game.current["keys"]) # Check if any CTRL key is pressed.
- game.current["plusDown"] = any(item in game.current["plus"] for item in game.current["keys"]) # Check if any + key is pressed.
- game.current["minusDown"] = any(item in game.current["minus"] for item in game.current["keys"]) # Check if any - key is pressed.
- # Switching the testing mode on and off. Ctrl-T
- # [CTRL] [T]
- if game.current["ctrlDown"] and 116 in game.current["keys"]:
- game.current["testing"] = not game.current["testing"]
- game.current["keys"].remove(116)
-
- if game.current["testing"]:
- layers.append(testing.layer(game))
- # Scaling the layer to the window size
- main_layer.scale(game.settings["pixels"],
- game.settings["pixels"])
- ui.color(game, main_layer, "black")
- main_layer.rectangle(0,0,
- game.current["w"],
- game.current["h"])
- main_layer.fill()
-
- for layer in layers:
- # Setting the layer as a kind of brush
- main_layer.set_source_surface(layer, 0 , 0)
- # This is making the pixel art look pixalated
- p = main_layer.get_source()
- p.set_filter(cairo.FILTER_NEAREST)
-
- # Painting the layer
- main_layer.paint()
- # Update things when window is stretched
- if game.current["h"] != game.previous["h"]\
- or game.current["w"] != game.previous["w"]:
- for i in game.menus:
- if "buttons" in game.menus[i]:
- game.menus[i]["buttons"] = []
- if 65307 in game.current["keys"]:
- game.scene = "main_menu"
- # [CTRL] [+]
- if game.current["ctrlDown"] and game.current["plusDown"]:
- game.settings["pixels"] += 1
- #save_settings(game)
- for key in game.current["plus"]:
- try:
- game.current["keys"].remove(key)
- except:
- pass
- # [CTRL] [-]
- if game.current["ctrlDown"] and game.current["minusDown"] and game.settings["pixels"] >1:
- game.settings["pixels"] -= 1
- #save_settings(game)
- for key in game.current["minus"]:
- try:
- game.current["keys"].remove(key)
- except:
- pass
-
- previous(game) # Go back to the previous screen
- # Refreshing the frame automatically
- gamedrawing.queue_draw()
-
- # Mouse
- def mouse_button_press(widget, event, game):
- # This function marks activation of the button. Not it's deactivation.
- for i, button in enumerate(["LMB", "MMB", "RMB"]):
- if i+1 == int(event.get_button()[1]):
- game.current[button] = [event.x / game.settings["pixels"],
- event.y / game.settings["pixels"]]
-
- def mouse_button_release(widget, event, game):
-
- # This function reverses the effects of the mouse_button_press() function.
-
- for i, button in enumerate(["LMB", "MMB", "RMB"]):
- if i+1 == int(event.get_button()[1]):
- game.current[button] = False
- def key_press(widget, event, game):
- if event.keyval not in game.current["keys"]:
- game.current["keys"].append(event.keyval)
- game.current["key_letter"] = event.string
-
- def key_release(widget, event, game):
- # Key values represent an ASCII code of the key's character
- # So 'A' is 65 and 'a' is 97. To mitigate sticky keys when
- # Shift is pressed, we need to remove all versions of the keys.
- upper = ord( chr( event.keyval ).upper() ) # Uppercase version
- lower = ord( chr( event.keyval ).lower() ) # Lowercase version
- for i in (upper, lower, event.keyval):
- if i in game.current["keys"]:
- game.current["keys"].remove(i)
-
- # I also want to clean the key letter. Because other wise in the
- # script writer I had weird key presses all the time.
- if not game.current["keys"]:
- game.current["key_letter"] = ""
-
- def scrolling(widget, event, game):
- e, x, y = event.get_scroll_deltas()
- game.current["scroll"] = [x,y]
|