Last active
February 13, 2023 08:16
-
-
Save fox3000foxy/2d085403c7d403736308f86acc4011bd to your computer and use it in GitHub Desktop.
Ruin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## ORIGINAL GAME FROM FIME | |
from math import * | |
from ruin_move import * | |
from kandinsky import fill_rect as drawRect,draw_string as drawTxt,get_pixel as getPxl | |
#from ion import keydown as key | |
from time import monotonic as cTime,sleep | |
from random import randint as rInt,seed as rSeed | |
TARG_SPF=0.02 #50fps | |
BG_COL,PL_COL,PTF_COL,NMY_COL,NMY_COL2,BLACK=(75,40,40),(240,10,10),(200,100,100),(0,150,255),(0,50,200),(0,0,0) | |
NAME,AUTH,START_MSG,EDITOR_URL=" R U | N "," by F | M E ","Press [OK] to start","/python/fime/ruin_lvl_maker" | |
SAVEFILE="ruin.sav" | |
def save_prog(lvl,frames): return | |
def load_prog():return 0,0 | |
class Entity(): | |
def __init__(it,x,y,w,h,drawFonc): | |
it.x,it.y,it.w,it.h=x,y,w,h | |
it.draw=lambda:drawFonc(it) | |
def hitBox(it,it2): | |
if it.x<it2.x+it2.w and it2.x<it.x+it.w and it.y<it2.y+it2.h and it2.y<it.y+it.h:return 1 | |
return 0 | |
class Platform(Entity): | |
def __init__(it,x,y,w,h,n): | |
super().__init__(x,y,w,h,drawPlatform) | |
it.order=n | |
def hitBox(it,it2): | |
if super().hitBox(it2) and it2.y+it2.h<it.y+it.h:return 1 | |
return 0 | |
class Movable(Entity): | |
def __init__(it,*arg): | |
super().__init__(*arg) | |
it.vx,it.vy,it.grounded=0,0,0 | |
def setVel(it,vx,vy):it.vx,it.vy=vx,vy | |
def addVel(it,vx,vy): | |
it.vx+=vx | |
it.vy+=vy | |
def applyPhysics(it): | |
if it.grounded: | |
it2=it.grounded | |
it.vy=0 | |
if it.x>it2.x+it2.w or it2.x>it.x+it.w: | |
it.grounded=0 | |
else : | |
it.addVel(0,0.2) | |
it.y+=min(it.vy,4) | |
it.vx/=1.3 | |
it.x+=it.vx | |
it.x=max(min(it.x,320-it.w),0) | |
def onPlatform(it,plat): | |
if plat.hitBox(it) and not it.grounded and it.vy>0: | |
it.grounded=plat | |
it.vy,it.y=0,plat.y-it.h | |
def jump(it):it.vy,it.grounded=-4.3,0 | |
class Enemy(Movable): | |
def __init__(it,*arg): | |
super().__init__(*list(arg)+[drawEnemy]) | |
def applyPhysics(it): | |
if it.grounded: | |
it2=it.grounded | |
if it2.w>20: | |
if it.x<it2.x+it.w: | |
it.vx+=0.05 | |
elif it.x>it2.x+it2.w-it.w*2: | |
it.vx-=0.05 | |
elif it.vx==0: | |
it.vx=1 | |
super().applyPhysics() | |
it.vx*=1.3 | |
class Bullet(Movable): | |
def __init__(it,it2,input_vy): | |
super().__init__(it2.x+it2.w/2,it2.y+it2.h/2,3,3,drawBullet) | |
it.setVel(copysign(3,it2.vx)+it2.vx,it2.vy+input_vy*2-1) | |
def applyPhysics(it): | |
it.addVel(0,0.2) | |
it.x+=it.vx | |
it.y+=it.vy | |
def fade(col1,col2,n):return tuple([i1*(1-n)+i2*n for i1,i2 in zip(col1,col2)]) | |
def shadow(it): | |
for i in range(1,6): | |
drawRect(int(it.x-i*2),int(it.y+i*it.h),it.w-i,it.h,fade(BLACK,BG_COL,i/6)) | |
def drawBaseEntity(it,col): | |
drawRect(int(it.x+2),int(it.y),it.w-2,it.h,col) | |
drawRect(int(it.x),int(it.y),2,it.h,BLACK) | |
def drawPlayer(it): | |
drawBaseEntity(it,PL_COL) | |
drawRect(int(it.x+it.w/2),int(it.y+7),2,3,BLACK) | |
for i in (3,it.h-3):drawRect(int(it.x+i+it.vx/4),int(it.y+2),2,2,BLACK) | |
def drawEnemy(it): | |
drawBaseEntity(it,NMY_COL) | |
drawRect(int(it.x+2),int(it.y+it.h/2),it.w-2,it.h//2,NMY_COL2) | |
for i in (3,it.h-3):drawRect(int(it.x+i),int(it.y+it.h/2-2),2,5,BLACK) | |
def hideEntity(it): | |
drawRect(int(it.x),int(it.y),int(it.w),int(it.h),BG_COL) | |
def drawPlatform(it): | |
drawBaseEntity(it,PTF_COL) | |
shadow(it) | |
def drawDoor(it): | |
drawRect(int(it.x),int(it.y),it.w,it.h,BLACK) | |
for i in range(1,5): | |
drawRect(int(it.x+1),int(it.y+it.h-i*2),int(it.w/2-i*2+3),1,fade(PTF_COL,BLACK,i/6)) | |
def drawBullet(it):drawRect(int(it.x),int(it.y),it.w,it.h,PTF_COL) | |
def createDoor(l1): | |
x,y,w,h=l1 | |
x,y,w,h=x+w//2-7.5,y-15,15,15 | |
return Entity(x,y,w,h,drawDoor) | |
def createPlayer(l1): | |
x,y,w,h=l1 | |
y,w,h=y-10,10,10 | |
return Movable(x,y,w,h,drawPlayer) | |
def createEnemy(l1,id): | |
x,y,w,h=l1 | |
x,y,w,h=x+10*id,y-10,10,10 | |
return Enemy(x,y,w,h) | |
def unpackPlatforms(n,type): | |
string=levels(type)[n] | |
Hex2Int=lambda n:int("0x"+n) | |
level=[] | |
for i in range(0,len(string),9): | |
ptf_str=string[i:i+9] | |
plat=[] | |
for j in range(0,8,2):plat+=[Hex2Int(ptf_str[j:j+2])*5] | |
plat.append(int(ptf_str[-1])) | |
level.append(plat) | |
return level | |
def loadLevel(lvl,type): | |
lowestPlatformY=0 | |
file=unpackPlatforms(lvl,type) | |
platforms,enemies=[],[] | |
for j in range(0,len(file)): | |
i=file[j] | |
platforms+=[Platform(n=j,*i[0:4])] | |
if lowestPlatformY<i[1]: | |
lowestPlatformY=i[1] | |
if i[4]: | |
enemies+=[createEnemy(i[0:4],j) for j in range(i[4])] | |
player,door=createPlayer(file[0][0:4]),createDoor(file[-1][:4]) | |
return [player,platforms,enemies,door,lowestPlatformY] | |
def titleAnim(h=150): | |
y,s_init,p=int(h),20,0 | |
drawRect(0,0,320,222,BG_COL) | |
while y>5: | |
if key(4):p=1 | |
s=(1-y/h)*s_init+p | |
y=round(y-s,1) | |
sleep(TARG_SPF*2) | |
if p:drawRect(0,0,320,222,BG_COL) | |
drawTxt(NAME,160-len(NAME)*5,int(101+h-y),BG_COL,PTF_COL) | |
drawTxt(AUTH,160-len(AUTH)*5,int(131+h-y),PTF_COL,BG_COL) | |
drawTxt(START_MSG,160-len(START_MSG)*5,int(181+h-y),fade(BG_COL,PL_COL,abs(sin(cTime()))),BG_COL) | |
def shortTransition(): | |
for i in range(30):drawRect(0,0,320,222,fade(BG_COL,BLACK,sin(i/30))) | |
def releaseKey(x): | |
while key(x):pass | |
def levels(lvl_type): | |
if lvl_type!="custom":return ("011606010071632010391606010", | |
"011606010111606010231606010341606010", | |
"0216060101e1601010331606010", | |
"042306010161c060100e1410011290f06011350f06010", | |
"08280601026280a011342102010291b020100f1b0201003140a011190d0201026080a010", | |
"0624060101a28020102b220201031190a01118160a0110a0e020101b070201030070a010", | |
"0527060101927010102a27010103420060112819060110c19060110511010100b09010101a060a013330606010", | |
"0428060100c2001010041c010100c16010102f1e01010391801010301101010260b0601012070a010", | |
"0128060101526010103026010103921010102d1a010101a1501010230e01010310d0a010", | |
"052506010051e06011051606011050f06011050806011301806010", | |
"0628060101623060110c1e020101719020102b19020103b12020102b0c02010170c02010060906010", | |
"0228060101d28060103122060111d1d020100e1b020100515020100e0f02010240d06011320d06010", | |
"0105040100c05350100823010101a1f060111e1801010341206011280e06010280e06010", | |
"362706010292006011351a020102f1302010042006011041706011080f010100c0706010", | |
"032806010242806011342106011251906011081901010021201010090c01010150706011270706010", | |
"042806010192306011251e06010311a060112514060100316060110a0e01010140806010", | |
"3726060101f2601010042601010081e010101019010102519010102f1006011220b06010", | |
"1a28060102a2306010331b01010251701010141706011051201010100a010101c0606010", | |
"0327060100c20010101619010102119030112d1903011351306010260a060111a0a01010050a06010", | |
"0220060101d1b020113117020111c0f06010", | |
"2f28060101428040110422020100e1b04010271a04011321402010270e040110e0e04011040806010") | |
else:return []#insert your lvl here | |
class GameEngine(): | |
def __init__(it,lvl_type="original",level=0): | |
it.status,it.lvl_type,it.lvl_nb=0,lvl_type,len(levels(lvl_type)) | |
it.lvl,it.total_frame,it.ded=level,0,False | |
def nextLevel(it): | |
if it.status==2: | |
it.playTransition(mode=1) | |
it.lvl+=1 | |
save_prog(it.lvl,it.total_frame) | |
it.playTransition() | |
else:shortTransition() | |
def endMsg(it): | |
t=it.total_frame*TARG_SPF | |
msg=["You finished the ", | |
"{} original levels !".format(it.lvl_nb), | |
"","Virtual time: {} min {}s".format(t//60,round(t%60,2)), | |
"","Download the level maker at :", | |
"my.numworks.com", | |
EDITOR_URL] | |
if it.lvl_type=="custom":msg=[msg[3]] | |
for i,txt in enumerate(msg): | |
drawTxt(txt,160-len(txt)*5,111-(len(msg)//2-i)*20,PTF_COL,BG_COL) | |
save_prog(0,0) | |
it.lvl,it.frame_nb=0,0 | |
while not key(4): | |
drawTxt("Press [OK]",210,200,fade(BG_COL,PL_COL,abs(sin(cTime()))),BG_COL) | |
def playTransition(it,h=222,mode=0): | |
try:l=loadLevel(it.lvl,it.lvl_type) | |
except:return | |
entities,s_init,y=l[1]+[l[3]],20,int(h) | |
if not mode: | |
entities+=[l[0]]+l[2] | |
for entity in entities:entity.y-=y | |
del l | |
while 1: | |
if y<1:break | |
if mode:s=(1-y/h)*s_init+5 | |
else:s=sqrt(y/h)*s_init | |
y=round(y-s,1) | |
sleep(TARG_SPF*2) | |
drawRect(0,0,320,222,BG_COL) | |
for entity in entities: | |
entity.y+=s | |
entity.draw() | |
def playLevel(it): | |
drawRect(0,0,320,222,BG_COL) | |
player,platforms,enemies,door,lowestPlatformY=loadLevel(it.lvl,it.lvl_type) | |
frame_nb,shot_frame,bullets,it.status=0,0,[],0 | |
isStatic=[0]*10 | |
surviveTime=0 | |
moveList=[] | |
while it.status==0: | |
t=cTime() | |
"frame_nb+=1" | |
frame_nb+=1 | |
surviveTime+=1 | |
player.addVel(key(3)-key(0),0.1*(1-key(4))) | |
if (frame_nb+9)%10==0:door.draw() | |
for b in bullets: | |
hideEntity(b) | |
b.applyPhysics() | |
if b.y>222:bullets.remove(b) | |
else:b.draw() | |
for movable in enemies+[player]: | |
hideEntity(movable) | |
if movable!=player: | |
if movable.hitBox(player): | |
it.status=1 | |
break | |
if frame_nb-shot_frame>10 and abs(movable.x-player.x)<50 and abs(movable.y-player.y)<20: | |
enemies.remove(movable) | |
#shot_frame=frame_nb | |
#bullets+=[Bullet(player,key(2)-key(1))] | |
for b in bullets: | |
if b.hitBox(movable): | |
movable.addVel(b.vx/3,b.vy/3) | |
if movable.y>222: | |
enemies.remove(movable) | |
movable.applyPhysics() | |
for platform in platforms: | |
movable.onPlatform(platform) | |
if (frame_nb+9)%10==0 and movable==player:platform.draw() | |
movable.draw() | |
if frame_nb-shot_frame>10 and key(16): | |
shot_frame=frame_nb | |
bullets+=[Bullet(player,key(2)-key(1))] | |
if player.grounded: | |
if key(4):player.jump() | |
if player.hitBox(door)==1:it.status=2 | |
if player.y>222:it.status=1 | |
while cTime()-t<TARG_SPF:pass | |
if key(17): | |
drawTxt(" P A U S E D ",95,101,BG_COL,PTF_COL) | |
frame_nb+=10-frame_nb%10 | |
releaseKey(17) | |
while not key(17):pass | |
releaseKey(17) | |
drawRect(95,101,130,20,BG_COL) | |
autocontrols(player,platforms) | |
#""" | |
level=0 | |
game=GameEngine(lvl_type="",level=level)#"custom" for custom lvl | |
#titleAnim() | |
#game.playTransition() | |
#""" | |
while 1: | |
if game.lvl>=game.lvl_nb: | |
game.endMsg() | |
game.playLevel() | |
game.nextLevel() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from math import * | |
from ion import * | |
overPress=[0]*45 | |
def key(e): | |
return keydown(e) or overPress[e] | |
def overwritePress(e,state): | |
overPress[e] = state | |
actual=0 | |
actualP=None | |
next=None | |
def autocontrols(player,platforms): | |
global actual | |
global actualP | |
global next | |
if player.grounded: | |
#print(actual,len(platforms)-1) | |
actual=player.grounded.order | |
if actual==len(platforms)-1: | |
return | |
actualP=platforms[actual] | |
next=platforms[actual+1] | |
if player.x<=next.x-5: | |
overwritePress(KEY_RIGHT,True) | |
overwritePress(KEY_LEFT,False) | |
if player.x+5>=actualP.x+actualP.w: | |
overwritePress(KEY_OK,True) | |
else: | |
overwritePress(KEY_OK,False) | |
elif player.x>=next.x+next.w-5: | |
overwritePress(KEY_RIGHT,False) | |
overwritePress(KEY_LEFT,True) | |
if player.x<=actualP.x+5: | |
overwritePress(KEY_OK,True) | |
else: | |
overwritePress(KEY_OK,False) | |
else: | |
overwritePress(KEY_RIGHT,False) | |
overwritePress(KEY_LEFT,False) | |
if(player.y>next.y): | |
overwritePress(KEY_OK,True) | |
else: | |
overwritePress(KEY_OK,False) | |
#print(player.x,actualP.x+actualP.w,next.x) | |
import ruin_for_ai |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment