cal_culator_demo_2.py

Created by heredos-me

Created on October 24, 2022

8 KB

CALculator (demo2)

This is a numworks demake of the cats are liquid game by last quarter studios.
In it’s current state, it is more of a proof of concept than a real game. Still, the scrolling and the physics engine are pretty powerful considering the platform, and even if the code is not commented, you should be able to reuse them, mod them, and do your own game with them.
I don’t regret at all the time spent on this I could’ve used studying in math class, i just hope that my grades won’t be that bad at the end of the year…



how to play?

The game have very basic controls:

  • (home) to go back to the menu
  • (OK) to jump
  • D-pad left and D-pad right to move
  • D-pad UP to turn into gas (you can float very high very fast but you can't move)
  • D-pad DOWN to turn into liquid (you can move very fast, go in small holes and you fall a bit faster, but you can't jump)

license

I don’t think this is necessary but just in case, i put this game, this engine, the sprites and all of the code under a permissive creative commons 4.0 attribution license Creative Commons Licence
This means that you can share, modify, study, and do everything you want with my work as long as you tell others that i, heredos, am the author of the original work.
Please also note that the idea of the game, the lumi character, and all of the source material i used as an inspiration are the property of Last Quarter Studios Limited Partnership, and i DO NOT own any of them.


technical notes

I removed all the comments because it would take too much space on the small


from random import randint
from time import sleep
from kandinsky import *
from ion import *

class sp:
  def ld(self,c,sx):
    a=0
    self.bmp=[]
    while c>0:
      self.bmp+=[[]]
      for i in range(sx):
        self.bmp[a]+=[c%2]
        c=c//2
      a+=1
  def __init__(self):
    self.bmp=[[],[]]
    self.size=(4,4)

  def drw(self,x,y,color):
    for i in range(len(self.bmp)):
      for j in range(len(self.bmp[i])):
        if self.bmp[i][j]:
          set_pixel(j+x,i+y,color)

  def drwr(self,x,y,r,color):
    if r==0:
      self.drw(x,y,color)
    elif r==1:
      a=len(self.bmp)
      for i in range(a):
        b=len(self.bmp[i])
        for j in range(b):
          if self.bmp[i][j]:
            set_pixel(x+a-i-1,y+j,color)
    elif r==2:
      a=len(self.bmp)
      for i in range(a):
        b=len(self.bmp[i])
        for j in range(b):
          if self.bmp[i][j]:
            set_pixel(x+b-j-1,y+a-i-1,color)
    elif r==3:
      for i in range(len(self.bmp)):
        b=len(self.bmp[i])
        for j in range(b):
          if self.bmp[i][j]:
            set_pixel(x+i,y+b-j-1,color)

sprites=(sp(),sp(),sp(),sp())
sprites[0].ld(8861580,6)
sprites[1].ld(72342380552863743,8)
sprites[2].ld(4340483223793664385,16)
sprites[3].ld(4359202964317896252,8)


def menu():
  fill_rect(0,0,320,222,(0,0,0))
  draw_string("CALculator beta 2",70,10)
  draw_string("press (OK) to play",65,40)
  draw_string("press (EXE) to quit",60,100)
  while 1:
    if keydown(KEY_OK):
      game()
    if keydown(KEY_EXE):
      exit()

def drwlumi():
  global sprites,xvel,yvel,form,lastform
  s=24
  p=(158,99)
  if form!=lastform:
    if lastform==2:
      a=int(xvel*2)
      if a>0:
        fill_rect(163-a-4,103,16+a,16,(0,0,0))
      if a<0:
        fill_rect(163+4,103,16-a,16,(0,0,0))
    if form==1:
      fill_rect(159,99,24,24,(255,255,255))
      sprites[1].drw(159,99,(0,0,0))
      sprites[1].drwr(175,115,2,(0,0,0))
      sprites[1].drwr(159,115,3,(0,0,0))
      sprites[1].drwr(175,99,1,(0,0,0))
      sprites[0].drw(163,105,(50,200,255))
      sprites[0].drw(173,105,(50,200,255))
      sprites[2].drw(163,113,(50,200,255))
    elif form==2:
      fill_rect(159,99,24,24,(0,0,0))
      fill_rect(163,103,16,16,(50,50,255))
      sprites[1].drwr(163+4+8,103,1,(0,0,0))
      sprites[1].drwr(163+4+8,111,2,(0,0,0))
      sprites[1].drw(163-4,103,(0,0,0))
      sprites[1].drwr(163-4,111,3,(0,0,0))
    elif form==0:
      fill_rect(159,99,24,24,(0,0,0))
      for i in range(16):
        sprites[3].drw(randint(159,175),randint(99,115),(100,100,100))
      sprites[0].drw(163,105,(50,200,255))
      sprites[0].drw(173,105,(50,200,255))
      sprites[2].drw(163,113,(50,200,255))
  elif form==2:
    a=int(xvel)
    if a>0:
      fill_rect(163-a-4,103,16+a,16,(50,50,255))
      fill_rect(163-a-4-a,103,a,16,(0,0,0))
      sprites[1].drw(163-a-4,103,(0,0,0))
      sprites[1].drwr(163-a-4,111,3,(0,0,0))
    if a<0:
      fill_rect(163+4,103,16-a,16,(50,50,255))
      fill_rect(163+16-a+4,103,16-a,16,(0,0,0))
      sprites[1].drwr(163-a+4+8,103,1,(0,0,0))
      sprites[1].drwr(163-a+4+8,111,2,(0,0,0))
def sgn(x):
  return -(x<0)+(x>0)
def col(r):
  for i in r:
    a=i

def game():
  global form
  global orientation
  global lastform
  global xvel
  fill_rect(0,0,xmax(),ymax(),(0,0,0))
  r=(rect(60,0,240,30),rect(100,100,15,15,(255, 126, 65)),rect(0,200,1000,100),rect(0,50,20,150),rect(300,0,150,180),
  rect(450,0,200,30),rect(500,170,200,30),rect(700,-100,20,300))
  orientation=(0,0)
  lastform=-1
  form=1

  xvel=0
  yvel=0
  x=0
  y=0
  onwall=False
  onground=0
  onceil=False

  box=((159,99,183,123),(159,99,183,123),(163,103,169,119))
  sprites=(sp(),sp(),sp(),sp())
  sprites[0].ld(8861580,6)
  sprites[1].ld(72342380552863743,8)
  sprites[2].ld(4340483223793664385,16)
  sprites[3].ld(4359202964317896252,8)
  drwlumi()
  lastform=1

  while 1:
    lastform=form
    if onground<=9:
      yvel+=(form+1)*0.2
    else:
      yvel=0
    if keydown(KEY_UP):
      if onceil:
        yvel=0
      elif onground>0 :
        form=0
        yvel=-10
        onground=0
      elif yvel>0 and form==0:yvel=0
    elif keydown(KEY_DOWN):
      form=2
      drwlumi()
      if lastform!=2:
        for i in r:
          i.erase(0,4)
        for i in r:
          i.rewrite(0,4)
    elif keydown(KEY_OK)|keydown(KEY_EXE):
      if onground>0:
        yvel=-10
        onground=0
      if onwall and not onceil:
        yvel=-2
      form=1
    else:
      form=1
    if lastform==2 and form!=2:
      tmp=False
      if onground:
        for i in r:
          if i.col(add(box[0],(0,-4,0,-4))):
            tmp=True
      else:
        for i in r:
          if i.col(box[form]):
            tmp=True
      if tmp:
        form=2
        if yvel<0:
          yvel=0
      else:
        if onground:
          for i in r:
            i.erase(0,-4)
          for i in r:
            i.rewrite(0,-4)
    if keydown(KEY_LEFT):
      xvel-=0.5
    elif keydown(KEY_RIGHT):
      xvel+=0.5
    else:
      xvel-=sgn(xvel)*0.1
    if keydown(KEY_HOME):
      menu()
    if abs(xvel)>(3*form**2) and xvel!=0:
      xvel-=sgn(xvel)
    drwlumi()
    onwall=False
    for i in r:
      i.erase(int(xvel),int(yvel))
    for i in r:
      i.rewrite(int(xvel),int(yvel))
      if i.col(add(box[form],(xvel,yvel,xvel,yvel))):
        if i.col(add(box[form],(xvel,-1,xvel,-1))):
          onwall=True
        if i.col(add(box[form],(0,yvel,0,yvel))):
          onground=10
    if onwall:
      xvel=-xvel
    onceil=False
    if onground>0:
      if yvel<0:
        yvel=-yvel
        onground=0
        onceil=True
      else:
        onground-=1
        yvel=0
    if onground<0:
      onground=0
    orientation=(sgn(xvel),sgn(yvel))
    if 0:
      fill_rect(0,0,40,40,(0,0,0))
      draw_string(str(onground)+str(yvel),0,0)
      sleep(0.05)

def xmax():
  return 340

def ymax():
  return 222

def add(a,b):
  d=min(len(a),len(b))
  c=[i for i in range(d)]
  for i in range(d):
    c[i]=a[i]+b[i]
  return c

class rect:
  def __init__(self,x,y,w,h,c=(255,255,255)):
    fill_rect(x,y,w,h,c)
    self.x=x
    self.y=y
    self.w=w
    self.h=h
    self.c=c
  def erase(self,ax,ay):
    ax,ay=-ax,-ay
    if self.col((0,0,xmax(),ymax())):
      if ax>0:
        fill_rect(self.x,self.y,ax,self.h,'black')
        self.x+=ax
      elif ax<0:
        fill_rect(self.x+self.w+ax,self.y,-ax,self.h,'black')
      self.w-=abs(ax)
      if ay>0:
        fill_rect(self.x,self.y,self.w,ay,'black')
        self.y+=ay
      elif ay<0:
        fill_rect(self.x,self.y+self.h+ay,self.w,-ay,'black')
      self.h-=abs(ay)
    else:
      if ax>0:
        self.x+=ax
      self.w-=abs(ax)
      if ay>0:
        self.y+=ay
      self.h-=abs(ay)
  def rewrite(self,ax,ay):
    ax,ay=-ax,-ay
    if self.col((-ax,-ay,xmax()-ax,ymax()-ay)):
      if ax>0:
        fill_rect(self.x+self.w,self.y,ax,self.h,self.c)
      elif ax<0:
        fill_rect(self.x+ax,self.y,-ax,self.h,self.c)
        self.x+=ax
      self.w+=abs(ax)
      if ay>0:
        fill_rect(self.x,self.y+self.h,self.w,ay,self.c)
      elif ay<0:
        fill_rect(self.x,self.y+ay,self.w,-ay,self.c)
        self.y+=ay
      self.h+=abs(ay)
    else:
      if ax<0:
        self.x+=ax
      self.w+=abs(ax)
      if ay<0:
        self.y+=ay
      self.h+=abs(ay)
  def col(self,r):
    return ((r[0]<self.x+self.w) and (r[2]>self.x)) and ((r[1]<self.y+self.h) and (r[3]>self.y))

def decomp_char(c):
  a=int("0x"+c)
  b=[]
  while a>0:
    b+=[a%2]
    a=a//2
  return b.reverse()

def intro():
  s="a project inspired by..."
  for i in range(len(s)):
    draw_string(s[i],35+10*i,101)
    sleep(0.05)
  for i in range(len(s)):
    fill_rect(35+10*i,101,10,20,(255,255,255))
    sleep(0.05)
  for i in range(90):
    for j in range(i):
      set_pixel(i-j-1+170,90-j+10,(0,0,0))
      set_pixel(90-(i-j-1)+60,j-1+121,(0,0,0))
      set_pixel(90-(i-j-1)+60,90-(j)+10,(0,0,0))
    sleep(0.0001)
  for i in range(45):
    for j in range(i):
      set_pixel(i-j-1+170,j+121,(255,200,100))
    sleep(0.01)
  for i in range(33):
    fill_rect(0,0,i*10,222,color(0,0,0))
    sleep(0.1)
  menu()
intro()