123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723 |
- # 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 json
- import cairo
- import math
- def load_palete(game):
- """Loads colors from assets/palete.json"""
- with open("assets/palete.json") as f:
- game.palete = json.load(f)
- def distance(list1, list2):
- """Calculates distnaces between two vectors"""
- d = []
- for n, i in enumerate(list1):
- try:
- d.append(max((i-list2[n]),(list2[n]-i)))
- except:
- d.append(0)
- return sum(d) / len(d)
- def color(game, layer, code, alpha=1):
- """Sets a cairo brush color from a palete by looking for the
- closest match."""
- # If it's a code in hex like #FF0000 so we need to convert it
- # to numbers first
- if type(code) == str and code.startswith("#") and (len(code) -1) %3 == 0:
- new_c = []
- for c in range(3):
- ind = int((len(code)-1)/3)
- new_c.append( int(code[ind*c+1:ind*c+ind+1], 16)/255 )
- code = new_c
- # If it's a code in RGB, we look for the nearest
- # color on the palete.
-
- if type(code) == list or type(code) == tuple:
- name = "black" # Place holder for a palete entry
- dist = 10000000000 # Imaginary large number
- # Chekcing for the lowest possible deviation of color
- for color in game.palete:
- new_dist = distance(game.palete[color], code)
- if dist > new_dist:
- name = color
- dist = new_dist
- r, g, b = game.palete[name]
- elif type(code) == str:
- try:
- r, g, b = game.palete[code]
- except:
- r, g, b = 0, 0, 0
- else:
- r, g, b = 0, 0, 0
- layer.set_source_rgba(r,g,b,alpha)
- def cache_sprite_sheet(game, sheet, asset=False):
- """This function will cache sprite sheets into game.images"""
- if sheet not in game.images:
- # Loading the sheet image
- grid = cairo.ImageSurface.create_from_png(sheet)
- # Loading metadata
- try:
- with open(sheet.replace(".png", ".json")) as f:
- metadata = json.load(f)
- except:
- metadata = {}
-
- width = 1
- height = 1
- try:
- width = metadata["resolution"][0]
- height = metadata["resolution"][1]
- except:
- pass
-
-
- # Getting the resolution of the cell
- cellx = int(grid.get_width()/width)
- celly = int(grid.get_height()/height)
- data = {}
- if asset:
-
- game.elements[asset[0]][asset[1]] = []
-
- for x in range(width):
- for y in range(height):
- # Creating individual cells
- cell = cairo.ImageSurface(cairo.FORMAT_ARGB32,
- cellx,
- celly)
- drawcell = cairo.Context(cell)
- drawcell.set_antialias(cairo.ANTIALIAS_NONE)
- drawcell.set_source_surface(grid,
- 1-(cellx*x+1),
- 1-(celly*y+1))
- drawcell.paint()
- # Putting the cell into the data as in "0:0" or "43:69".
- cellname = str(x)+":"+str(y)
- cellnameindata = cellname
- celldata = {}
- try:
- #print("SEE IT PLEASE!", game.elements[asset[0]][asset[1]])
-
- if asset and metadata[cellname] not in game.elements[asset[0]][asset[1]]:
-
- game.elements[asset[0]][asset[1]].append(metadata[cellname].copy())
- cellnameindata = metadata[cellname]["title"]
- celldata = metadata[cellname]
- except:
- pass
- celldata["binary"] = cell
- if cellnameindata not in data:
- data[cellnameindata] = [celldata]
- else:
- data[cellnameindata].append(celldata)
- try:
- data["title"] = metadata["title"]
- except:
- data["title"] = sheet
- try:
- data["menu_color"] = metadata["menu_color"]
- except:
- data["menu_color"] = "#000000"
- try:
- data["authors"] = metadata["authors"]
- except:
- try:
- data["authors"] = metadata["autors"]
- except:
- data["authors"] = []
- try:
- data["licenses"] = metadata["licenses"]
- except:
- data["licenses"] = []
-
- #data["current_frame"] = 0 # Don't need it quite yet
-
- game.images[sheet] = data
-
- def image(game, layer, x, y, name, code="0:0", color=False, offset=False, alpha=1, frame=None, dynamic=False):
- x = int(x)
- y = int(y)
-
- """This function draws an image into a canvas. And load it if
- it's not loaded"""
- # Load the whole image as a sprite ( if it's not loaded yet )
- cache_sprite_sheet(game, name)
- # Drawing the image
-
- source = game.images[name].get(code,
- list(game.images[name].values())[-5])
- # We need to know what frame of an animation to use 'anim_pulse' and
- # how much frames ago the pulse was changed. We record the current frame
- # into the "anim_last" on every change.
-
- if "anim_pulse" not in game.current:
- game.current["anim_pulse"] = 0
- if "anim_last" not in game.current:
- game.current["anim_last"] = game.current["frame"]
-
- # And so if a specific amount of frames ( 1 second of frames / 10 ) is passed
-
- if ( game.current["frame"] - game.current["anim_last"] ) > int(game.FPS/10):
- game.current["anim_pulse"] += 1 # We advance one frame
- game.current["anim_last"] = game.current["frame"] # And we record the time of
- # this change
- # The current frame is the modulo of the 'anim_pulse' by the amount of frames in
- # this particular animation.
- if frame == None:
- cf = game.current["anim_pulse"] % len(source)
- else:
- cf = frame
-
- if offset:
- off = source[cf].get("offset", [0,0])
- x += off[0]
- y += off[1]
- if dynamic:
- x -= int(64/2)
- y -= int(36/2)
-
-
-
- if color: #If we forcing color
-
- layer.mask_surface(source[cf]["binary"],x, y)
- layer.set_antialias(cairo.ANTIALIAS_NONE)
- p = layer.get_source()
- p.set_filter(cairo.FILTER_NEAREST)
- layer.fill()
- else: #If we just using the image
-
- layer.set_source_surface(source[cf]["binary"], x, y)
- layer.set_antialias(cairo.ANTIALIAS_NONE)
- p = layer.get_source()
- p.set_filter(cairo.FILTER_NEAREST)
- if alpha == 1:
- layer.paint()
- else:
- layer.paint_with_alpha(alpha)
-
- def text(game, layer, string, x, y, color=True, align="left"):
- """This function will draw text using an assets/font.png file."""
- for n, l in enumerate(string):
- ax = x+(8*n)
- if align == "center":
- ax = ax - int(len(string)*4)
- elif align == "right":
- ax = ax - int(len(string)*8)
- image(game, layer, ax, y, "assets/font.png", l, color=color)
-
- def button(game, layer, x, y, w, h,
- menu="", icon="", string="", func=False,
- scroll="", borders=True, btnTxtColor="#00FF00"):
- """Draws a button"""
-
- # Let's add this button into a menu.
- menu_selected = False
- select_number = 0
-
- if menu:
- if menu not in game.menus :
- game.menus[menu] = {"selected":0,
- "buttons":[]}
- bmenudata = [x,y]
- if bmenudata not in game.menus[menu]["buttons"]:
- game.menus[menu]["buttons"].append(bmenudata)
-
- for n, i in enumerate(game.menus[menu]["buttons"]):
-
- if i == bmenudata:
-
- select_number = n
- if n == game.menus[menu]["selected"]:
- menu_selected = True
- if scroll and scroll in game.scroll:
-
- # Making sure that while I press either UP or DOWN it will
- # scroll to the correct spot.
- if (65362 in game.current["keys"]\
- or 65364 in game.current["keys"])\
- and menu_selected:
- game.scroll[scroll] = 0 - y + int(game.current["h"] / 2)
- y = y + int(game.scroll[scroll])
-
-
- x = int(round(x))
- y = int(round(y))
- w = int(round(w))
- h = int(round(h))
-
-
- color(game, layer, btnTxtColor)
- layer.set_line_width(1)
- if borders:
- layer.rectangle(x,y,w,h)
- layer.stroke()
-
- mo = False
- if int(game.current["mx"]) in range(x, x+w) \
- and int(game.current["my"]) in range(y, y+h):
- mo = True
-
- if mo or menu_selected:
- if menu:
- game.menus[menu]["selected"] = select_number
-
- if mo:
- layer.rectangle( x+1,y+1, w-3, h-3 )
- layer.fill()
- else:
- #layer.rectangle( x+1,y+1, w-2, h-2 )
- #layer.stroke()
- #Fancy lines
- layer.set_line_width(3)
-
- layer.move_to(x,y+h/3)
- layer.line_to(x,y)
- layer.line_to(x+w/3, y)
- layer.stroke()
- layer.move_to(x+w,y+h-h/3)
- layer.line_to(x+w,y+h)
- layer.line_to(x+w-w/3, y+h)
- layer.stroke()
-
- layer.set_line_width(1)
- # If you clicked the button
- if ( game.previous["LMB"] \
- and int(game.previous["LMB"][0]) in range(x, x+w) \
- and int(game.previous["LMB"][1]) in range(y, y+h) ) \
- or ( menu_selected and 65293 in game.previous["keys"]):
- color(game, layer, "yellow")
- layer.rectangle( x+1,y+1, w-3, h-3 )
- layer.fill()
- # If the is doing something
- if (( not game.current["LMB"] and game.previous["LMB"] and mo) \
- or (65293 not in game.current["keys"] \
- and 65293 in game.previous["keys"])) \
- and func:
- func()
- game.previous["LMB"] = False
- game.current["LMB"] = False
- game.current["keys"] = []
- game.previous["keys"] = []
- if icon:
- if mo:
- color(game, layer, "black")
- image(game, layer, x+2,y+1,"assets/menu_icons.png",
- icon, True)
-
- if string:
- if mo:
- color(game, layer, "black")
-
- widthleft = w - 4
- xd = x
- if icon:
- widthleft -= 12
- xd += 12
- sl = int(widthleft / 8)
- if len(string)*8 > widthleft:
-
- fp = int(game.current["frame"]/10) % (len(string)+7)
- text(game, layer, (string+" "+string)[fp:fp+sl], xd+2, y-int(h/5)+3 )
- #elif len(string)*8 > widthleft:
- # text(game, layer, string[:sl-3]+"...", xd+2, y-int(h/5)+3 )
-
- else:
- text(game, layer, string, x+int(w/2), y-int(h/5)+3, align="center")
-
- def button_navigate(game, menu):
- """This function will run in each layer to provide keyboard navigation."""
- # We don't want to run it if non of the arrow keys are pressed.
- # Thus we check for either of the arrow keys is pressed.
- if 65361 in game.current["keys"]\
- or 65362 in game.current["keys"]\
- or 65363 in game.current["keys"]\
- or 65364 in game.current["keys"]:
- # We want to know things about the currently selected button
- select = game.menus[menu]["selected"] # It's number in the list
- cur = game.menus[menu]["buttons"][select] # It's coordinates x, y
- prevdistance = 100000000000 # Arbitrary huge number
- # For all buttons in the menu list, we are going to see if it's
- # in a correct direction from the currently selected button, based on
- # the arrow key:
- # 65361 - RIGHT
- # 65362 - UP
- # 65363 - LEFT
- # 65364 - DOWN
- # But since there could be more then one button towards the correct
- # side, we are also checking for the closest one ( by comparing the
- # lowest possible distance to the currently selected button ).
-
- for n, i in enumerate( game.menus[menu]["buttons"] ):
- curdistance = distance(i, cur)
- if ((65361 in game.current["keys"] and i[0] < cur[0] )\
- or (65362 in game.current["keys"] and i[1] < cur[1] )\
- or (65363 in game.current["keys"] and i[0] > cur[0] )\
- or (65364 in game.current["keys"] and i[1] > cur[1] ))\
- and (curdistance < prevdistance)\
- and i != cur:
- select = n
- prevdistance = curdistance
- # And we restart keys, so it will not do this on each frame
- game.current["keys"] = []
- # And we write the number of the selected key
- game.menus[menu]["selected"] = select
-
-
- def scroll_area(game, layer, menu, x, y, width, height, max_value,
- strenght=6):
- """This function makes an invisible area in the UI, where there
- could be scroolling."""
-
- if max_value == 0:
- max_value = 1
-
- x = int(x)
- y = int(y)
- width = int(width)
- height = int(height)
- max_value += 5
- amount = 0.0
- if int(game.current['mx']) in range(x, x+width) \
- and int(game.current['my']) in range(y, y+height):
-
- amount = game.current["scroll"][1] * strenght
- game.current["scroll"] = [0, 0]
- # Middle mouse drag ( for those who have no working wheel
- # like myself, lol )
-
- if game.current["MMB"]\
- and int(game.current["mx"]) in range(x, x+width)\
- and int(game.current["my"]) in range(y, y+height):
- amount = 0- ( game.current["my"] - game.previous["my"] )
- def logic():
-
- # Scroll logic
- game.scroll[menu] -= amount
-
- # If too low
- if game.scroll[menu] < (1-max_value+height):
- game.scroll[menu] = (1-max_value+height)
- # If too high
- if game.scroll[menu] > 0:
- game.scroll[menu] = 0
-
-
- logic()
- if game.current["testing"]:
- color(game, layer, "red")
- layer.rectangle(x,y+1,width-1,height-1)
- layer.stroke()
- def blur(surface, game, amount):
-
- # This function will blur a given layer by scaling it down and scaling it
- # back up. It will be doing it only when a given blur setting it active.
-
- # To avoid all kinds of Zero devision problems. And speed up the draw if
- # using animated blur values.
- if amount < 2: # When Blue value was less then 3 it felt sharp but not enough
- return surface # Which caused sense of uneasiness.
-
- # If to active blur. Will be changed in the graphics settings.
- if game.settings.get("Blur", True):
- # scaling down
- surface1 = cairo.ImageSurface(cairo.FORMAT_ARGB32, game.current['w'],
- game.current['h'])
-
- slacedownlayer = cairo.Context(surface1)
- slacedownlayer.scale(1/amount,
- 1/amount)
-
- slacedownlayer.set_source_surface(surface, 0 , 0)
- if game.settings["NN-Downscaler-Blur"]:
- p = slacedownlayer.get_source()
- p.set_filter(cairo.FILTER_NEAREST)
-
- slacedownlayer.paint()
-
- #scaling back up
- surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, game.current['w'],
- game.current['h'])
- slaceuplayer = cairo.Context(surface2)
-
- slaceuplayer.scale(amount,
- amount)
-
-
- slaceuplayer.set_source_surface(surface1, 0 , 0)
- if game.settings["NN-Upscaler-Blur"]:
- p = slaceuplayer.get_source()
- p.set_filter(cairo.FILTER_NEAREST)
- slaceuplayer.paint()
-
- return surface2
- else:
- return surface
- def round_rect(layer, x, y, width, height, r):
- if width < r*2:
- width = r*2
- if height < r*2:
- height = r*2
-
- layer.move_to(x,y+r)
- layer.arc(x+r, y+r, r, math.pi, 3*math.pi/2)
- layer.arc(x+width-r, y+r, r, 3*math.pi/2, 0)
- layer.arc(x+width-r, y+height-r, r, 0, math.pi/2)
- layer.arc(x+r, y+height-r, r, math.pi/2, math.pi)
- layer.close_path()
- def fancy_health_bar(game, x, y, w, h, oldlayer, value):
- # This is going to be a fancy health bar, dah.
-
- # Setting up a cairo layer
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
- int(w),
- int(h))
- layer = cairo.Context(surface)
- layer.set_antialias(cairo.ANTIALIAS_NONE)
- # RED PART
-
- round_rect(layer, 0,0, w,h,h/2)
- layer.clip()
-
- color(game, layer, "red")
- layer.rectangle(0,0,w,h)
- layer.fill()
- color(game, layer, "brown")
- layer.rectangle(0,0,w,h/3)
- layer.fill()
-
- color(game, layer, "dark_red")
- layer.rectangle(0,0,w,h/5)
- layer.fill()
- color(game, layer, "bright_pink")
- layer.rectangle(w/2,h-5,w*0.45, 2)
- layer.fill()
- # shadow
- color(game, layer, "dark_red")
- round_rect(layer, 0,0, (w*value)+5 ,h ,h/2)
- layer.fill()
- # GREEN PART
-
- round_rect(layer, 0,0, w*value ,h ,h/2)
- layer.clip()
-
- color(game, layer, "dark_green2")
- layer.rectangle(0,0,w,h)
- layer.fill()
- color(game, layer, "dark_green")
- round_rect(layer, 0-h/5,0-h/5, (w*value) ,h ,h/2)
- layer.fill()
- color(game, layer, "green")
- round_rect(layer, 0-h/3,0-h/3, (w*value) ,h ,h/2)
- layer.fill()
-
- color(game, layer, "bright_green")
- layer.rectangle(w*0.05,3,(w*0.45)*value, 2)
- layer.fill()
- oldlayer.set_source_surface(surface, x, y)
- oldlayer.paint()
- layer.set_line_width(1)
- color(game, oldlayer, "black")
- round_rect(oldlayer, x,y, w,h,h/2)
- oldlayer.stroke()
- def useless_interface_1(game, layer, x,y,w,h):
- # This will draw a background pattern
- frame = game.current["frame"]
- imx = max(w/3*2-100+30, w/3-30)
- imy = int(h/2)-75
-
-
- # 79th photo
- if frame > 60:
- factor = min(1, max((frame-60)/20, 0))
-
- color(game, layer, "green")
- layer.set_line_width(1)
- if frame > 80:
- layer.set_line_width(2)
-
- layer.move_to(imx-5, imy+5)
- layer.line_to(imx, imy-2)
- layer.line_to(imx+170*factor+5, imy-2)
- layer.line_to(imx+170*factor+5, imy+150*factor-2)
- layer.line_to(imx+170*factor, imy+150*factor+3)
- layer.line_to(imx-5,imy+150*factor+3)
- layer.line_to(imx-5,imy+5)
- layer.stroke_preserve()
-
-
- if frame > 80 and frame not in range(85, 90) and frame not in range(95,100):
- color(game, layer, "dark_blue")
- layer.fill()
- image(game, layer,
- imx-30,
- imy,
- "assets/menu-bg.png")
-
- # Buttons area
- if frame > 40:
- layer.set_line_width(2)
- else:
- layer.set_line_width(1)
- color(game, layer, "green")
- factor = min(1, max(frame/20, 0))
-
- layer.move_to(10,h-55*factor)
- layer.line_to(15, h-60*factor)
- layer.line_to(w/3+5, h-60*factor)
- layer.line_to(w/3+5, h-7)
- layer.line_to(w/3, h-3)
- layer.line_to(10,h-3)
- layer.line_to(10,h-55*factor)
- layer.stroke_preserve()
- if frame > 40 and frame not in range(45, 50) and frame not in range(55,60):
- color(game, layer, "dark_blue")
- layer.fill()
-
- factor = min(1, max((frame-40)/5, 0))
- color(game, layer, "green")
- layer.set_line_width(1)
- connectY = min(imy+150, h-70)
-
- layer.move_to(w/4, h-60)
- layer.line_to(w/4, (h-60)+((connectY-1)-(h-60))*factor)
- layer.stroke()
- factor = min(1, max((frame-45)/5, 0))
- layer.move_to(w/4, connectY)
- layer.line_to((w/4)+((imx-5)-(w/4))*factor, connectY)
- layer.stroke()
-
-
- if h > 200 and w > 400:
- if frame < 200:
- string = "I'm Not Even Human"
- part = max(0, min(int(frame/5)-20, len(string)))
- add_ = ""
- if part != len(string):
- add_ = "_"
- color(game, layer, "green")
- text(game, layer, string[:part]+add_,
- 15,
- 15)
- else:
- image(game, layer, 10, 15, "assets/game-title.png")
- else:
- text(game, layer, "INEH",
- 15,
- 15)
|