123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- # 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
- 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):
- """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 = {}
-
- 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)
- try:
- cellname = metadata[cellname]["title"]
- except:
- pass
-
- data[cellname] = cell
- game.images[sheet] = data
-
- def image(game, layer, x, y, name, code="0:0", color=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())[-1])
-
- if color: #If we forcing color
- layer.set_antialias(cairo.ANTIALIAS_NONE)
- layer.mask_surface(source,x, y)
- layer.fill()
- else: #If we just using the image
- layer.set_source_surface(source, x, y)
- layer.paint()
-
-
- 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=""):
- """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, "#FF0000")
- layer.set_line_width(1)
- 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
- layer.rectangle( x+1,y+1, w-3, h-3 )
- layer.fill()
- # 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 or menu_selected:
- color(game, layer, "black")
- image(game, layer, x+2,y+1,"assets/menu_icons.png",
- icon, True)
-
- if string:
- if mo or menu_selected:
- color(game, layer, "black")
- 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]
- #if game.current["MMB"]:
- # amount = 0- ( game.current["mx"] - game.previous["mx"] )
- 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()
|