0UUUU08hx0kkk@@PHȸ` `2TvͫgE#w`UDTwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww||||||||wwwwwwwwwwwwwwwwwwwwwwwww|wwwwwwwwwww|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww|wwwww|wwwwwwwwww|wwww||ww|ww|ww||ww|www||www|w|||||||||w|||||wwwwwwwwwwww|ww|wwwwwwwwwwww|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww||www|wwwwwwwwwwwwwwwwwwwwwwwwwwww|| ?<77<7wwwwwww||||ww|w|ww|||||||||||||||||||wwwwwwwwwww|wwwwwwwww|wwwwwwwwwwwww|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww|wwww|wwwwwwwwwwwwwwwwwwwwwwwwwwww|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwww||||||||||||||||||||||wwwwwwwwwwwww|wwwwwwwwwwwwwwwwww|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww|wwwwwwwwwwwwwwww|wwwwwwwww|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww||||wwwww|wwwwwwwwwwwww<|||swp7| w|<| <777wss sp w |< w s|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww|||wwwww|w|w|w|w| |ws|wsswsp <=hit.x and y==hit.y then local dist=math.abs((hit.x-x)*2) hy=(t-hit.t)-dist end tile=remap(tile,x,y) spr(tile,(x*8)+ox,(y*8)+oy-hy,cc,1) end end end for x=cx,cx+w do for y=cy,cy+h do local tile=mget(x,y) local change=false if t%4==0 and tile==36 and solids[mget((x+1)%32,y)] and mget((x+1)%32,y)~=36 then mset((x+1)%32,y,36) change=true end if t%4==0 and tile==36 and solids[mget((x-1)%32,y)] and mget((x-1)%32,y)~=36 then mset((x-1)%32,y,36) change=true end if change then return end end end if hit and t-hit.t>=8 then hit=nil end end function pmusic() local m=peek(0x13FFC) return m==1 or m==2 end function sol(x,y) return solids[mget(x//8,y//8)] end function col(x1,y1,w1,h1, x2,y2,w2,h2) return x1 < x2+w2 and x2 < x1+w1 and y1 < y2+h2 and y2 < y1+h1 end function pal(c0,c1) if(c0==nil and c1==nil)then for i=0,15 do poke4(0x3FF0*2+i,i)end else poke4(0x3FF0*2+c0,c1)end end function fontc(t,x,y,c,center) local w=font(t,0,-200) if c then pal(15,c) end font(t,x-(center and (w/2) or 0),y) pal() end function doScores() for i,v in pairs(scores) do spr(190,v.x+mx,v.y+my,8,1,0,0,2,1) v.y=v.y-.5 if t-v.t>20 then table.remove(scores,i) end end end function resetPOW() mset(15,20,1) mset(16,20,2) mset(15,21,17) mset(16,21,18) end function startScreen() cls(0) map(210,119,30,17,4,-4,0) fontc("2022 orange pixltrash",119,84,15,true) fontc("ORIGINAL BY NINTENDO",119,84+9,14,true) fontc("CLONE CODE BY vibVib",119,84+9+9,12,true) fontc("MUSIC COVER BY Dimon",119,84+27,11,true) fontc("--PRESS A TO PLAY--",119,135-10,9,true) --spr(48,6,135-10) if btnp(4) then state=1 music(1,-1,-1,false) end end function init() t=0 shake_t=-20 map_w=8*32 map_h=28*8 spawnx,spawny=15*8,23*8 step={0,4,7,4,7,4,7,4} p={x=spawnx,y=spawny,vx=0,vy=0,spr=256,update=updatePlayer,draw=drawPlayer,lives=3, anis={ idle={208}, run={210,212,214}, jump={218}, fall={210}, slide={216}, hurt={220}, dead={222}, }, stepid=0 } p.ani=p.anis.idle hit=nil hurt={420,422,424} anis={} anis.shell={ hit={416}, hurt={ {416,416,416,418,418,418}, {420,420,422,422}, {420,422,424}, }, walk={384,384,384,386,386,386}, dead={426} } anis.crab={ hit={456}, hurt={ {458,458,458,460,460,460}, {458,458,460,460}, {458,460} }, walk={448,448,448,450,450,450}, angrywalk={452,452,452,454,454,454}, dead={456} } anis.fly={ stand={256,256,256,258,258,258}, walk={258,260,262}, hit={268}, hurt={ {268,268,268,270,270,270}, {268,268,270,270}, {268,270} }, dead={268} } anis.ice={ walk={480,480,482,482,484,484,488,488}, ice={462} } queue={} bads={} coins={} speeds={ice=.8,shell=.25,crab=.5,fly=.5} deads={} killed=0 spawned=0 state=0 score=0 phase=1 scores={} kills=0 parts={} pow_spr={[1]=true,[2]=true,[17]=true,[18]=true} resetPOW() music(0,-1,-1,true) phase_over=-50 ice_queue={} end function advancePhase() music(2,-1,-1,false) p.x,p.y=spawnx,spawny p.vx,p.vy=0,0 bads={} coins={} deads={} killed=0 spawned=0 phase=phase+1 if phase%5==0 then resetPOW() end for x=-1,32 do for y=-1,27 do if mget(x,y)==36 then mset(x,y,33) end end end end function endPhase() phase_over=t fontc("PHASE CLEAR",120,68+1,0,true) fontc("PHASE CLEAR",120,68,15,true) end function doCoins() if pmusic() then return end for i,v in pairs(coins) do if sol(v.x,v.y+16+v.vy) or sol(v.x+15,v.y+16+v.vy) then v.vy=0 else v.vy=v.vy+.1 end if col(v.x,v.y,16,16,p.x,p.y,16,16) then collectCoin(v,i) end if v.y>21*8 then if v.x+v.vx>=map_w or v.x+v.vx<=0 then v.y=0 end end v.x=v.x+v.vx v.y=v.y+v.vy v.x=v.x%map_w v.spr=132+(t//6)%3 spr(v.spr,v.x+mx-4,v.y+my,0,1,0,0,1,2) end end function collectCoin(self,i) table.insert(scores,{x=self.x,y=self.y,t=t}) table.remove(coins,i) sfx(9) score=score+800 end function doParts() for i,v in pairs(parts) do v.t=v.t+1 if v.t>=20 then table.remove(parts,i) end v.x=v.x+rand(-1,1) v.y=v.y+rand(-1,1) v.x=v.x+v.vx v.y=v.y+v.vy circ(v.x+mx,v.y+my,v.s or 1.5,v.c or 15) end end function doBads() if pmusic() then return end for i,v in pairs(bads) do if sol(v.x,v.y+16+v.vy) or sol(v.x+15,v.y+16+v.vy) then v.vy=0 else v.vy=v.vy+.1 end if not v.hurt then if v.type~="fly" then v.vx=speeds[v.type]*v.dir*v.state else v.vx=.5 end if v.type=="crab" and v.angry then v.ani=anis[v.type].angrywalk else v.ani=anis[v.type].walk end if v.vx>0 then v.f=0 else v.f=1 end else if v.vy==0 then v.ani=anis[v.type].hurt[(((t-v.hurt_t)//100)%3)+1] v.vx=0 else v.ani=anis[v.type].hit end --REGAIN MOVEMENT AFTER TIME PERIOD if t-v.hurt_t>300 then v.vy=-2 v.hurt=false v.state=math.min(v.state+1,3) end end if v.type=="fly" and sol(v.x,v.y+16) and not v.hurt then v.vx=0 v.ani=anis.fly.stand end if v.type=="fly" and (t-v.t)%(200//v.state)==0 and sol(v.x,v.y+16) and not v.hurt then v.vy=-2 end local collide=false for oi,other in pairs(bads) do if col(v.x+v.vx,v.y,16,16,other.x,other.y,16,16) and i~=oi and not v.hurt then if not v.lastcol then v.dir=-v.dir end collide=true end end for oi,other in pairs(coins) do if col(v.x+v.vx,v.y,16,16,other.x,other.y,16,16) and not v.hurt then if not v.lastcol then v.dir=-v.dir end collide=true end end if v.type=="ice" then if mget((v.x)//8,(v.y+8)//8)==154 and mget((v.x)//8,(v.y+16)//8)~=36 then v.vx=0 if not v.ice_time then v.ice_time=0 end v.ani=anis.ice.ice v.ice_time=v.ice_time+1 if v.ice_time>=20 then mset((v.x)//8,(v.y+16)//8,36) mset((v.x+8)//8,(v.y+16)//8,36) end end end v.lastcol=collide v.x=v.x+v.vx v.y=v.y+v.vy v.x=v.x%map_w v.spr=v.ani[(((t)//3)% #v.ani)+1] if v.state==2 then if v.type=="shell" then pal(10,9) elseif v.type=="crab" then pal(9,10) elseif v.type=="fly" then pal(8,10) end elseif v.state==3 then if v.type=="shell" then pal(10,1) elseif v.type=="crab" then pal(9,8) pal(14,13) elseif v.type=="fly" then pal(8,1) end end if v.y>21*8 then if v.x+v.vx>=map_w or v.x+v.vx<=0 then v.y=0 end end spr(v.spr,v.x+mx,v.y+my,0,1,v.f,0,v.w or 2,v.h or 2) pal() --end end end function drawPlayer(self) self.spr=self.ani[(((t)//3)% #self.ani)+1] spr(self.spr,self.x+mx,self.y+my,0,1,self.f,0,2,3) if self.spawned then spr(37,self.x+mx,self.y+24+my,0,1,0,0,2,1) end end function hurtBad(self,i) if self.type=="ice" then for i=0,8 do table.insert(parts,{x=self.x+8,y=self.y+8,vx=rand()-.5,vy=rand()-.5,t=0,c=blues[rand(1,#blues)]}) end sfx(11,"C-7") table.insert(scores,{x=self.x,y=self.y,t=t}) score=score+800 killed=killed+1 table.remove(bads,i) end if (self.type=="crab" and self.angry) or self.type~="crab" then self.hurt=not self.hurt end if self.type=="crab" and not self.angry then self.angry=true end if self.hurt then self.hurt_t=t end end function updatePlayer(self) if pmusic() then self.ani=self.anis.idle return end if p.dead then self.ani=self.anis.hurt if self.y>map_h then --self.dead=false self.lives=self.lives-1 if self.lives==0 then state=2 return end music(3,-1,-1,false) self.spawned=true self.dead=false self.x,self.y=spawnx,-32 elseif t-p.deathtime>30 then self.vy=self.vy+.1 self.ani=self.anis.dead elseif t-p.deathtime==30 then self.vy=-2 else self.ani=self.anis.hurt self.vx,self.vy=0,0 end elseif self.spawned then --SPAWN AFTWER DEATH ABOVE MAP ON PLATFORM< DRAW PLATFORM BELOW IN MAIN CODE self.vx,self.vy=0,0 self.y=math.min(p.y+.25,0) self.ani=self.anis.idle self.f=1 if btnp()~=0 and self.y==0 then self.spawned=false self.vy=-2 sfx(8) end else local slide=.1 if mget((self.x)//8,(self.y+24)//8)==36 or mget((self.x+16)//8,(self.y+24)//8)==36 then slide=0.01 end if btn(2) then self.f=0 self.vx=math.max(self.vx-slide,-1) self.ani=self.anis.run if self.vx>=-.5 then self.f=1 self.ani=self.anis.slide end elseif btn(3) then self.f=1 self.vx=math.min(self.vx+slide,1) self.ani=self.anis.run if self.vx<=.5 then self.f=0 self.ani=self.anis.slide end else if self.vx>0 then self.vx=self.vx-(slide/2) elseif self.vx<0 then self.vx=self.vx+(slide/2) end if self.vx>-.1 and self.vx<.1 then self.vx=0 end --self.vx=0 self.ani=self.anis.idle end --JUMP if btnp(4) and (sol(self.x,self.y+24) or sol(self.x+15,self.y+24)) then self.vy=-3.5 self.ani=self.anis.jump sfx(8,"A-4",-1,1) end if sol(self.x,self.y+24+self.vy) or sol(self.x+15,self.y+24+self.vy) then self.vy=0 else self.vy=self.vy+.1 if self.vy<=0 then self.ani=self.anis.jump else self.ani=self.anis.fall end end if sol(self.x+15+self.vx,self.y+7) or sol(self.x+15+self.vx,self.y+15) or sol(self.x+15+self.vx,self.y+23) or sol(self.x+self.vx,self.y+7) or sol(self.x+self.vx,self.y+15) or sol(self.x+self.vx,self.y+23) then self.vx=0 end if self.vy<0 then if sol(self.x+self.vx,self.y+4+self.vy) or sol(self.x+15+self.vx,self.y+4+self.vy) and not pow_spr[mget((self.x+self.vx)//8,(self.y+self.vy)//8)] then self.vy=0 hit={x=((p.x+8)//8),y=((p.y-4)//8),t=t} for i,v in pairs(bads) do if (v.x+8>p.x) and v.x+8p.y-9 then v.vy=-2 --launch angle, iffy. Not sure the exact way this is calculated. v.vx=v.vx+(v.x-p.x)/8 hurtBad(v,i) end end for i,v in pairs(coins) do if (v.x-4p.x+8 and v.y+16>p.y-9 then collectCoin(v,i) end end --POW local x,y=(self.x)//8,(self.y-4)//8 if col(x,y,2,2,15,20,2,2) then mset(15,20,mget(15,20)+2) mset(16,20,mget(16,20)+2) mset(15,21,mget(15,21)+2) mset(16,21,mget(16,21)+2) shake_t=t sfx(0,"F-1",-1,0,15,-1) for i,v in pairs(bads) do if sol(v.x,v.y+16) or sol(v.x+15,v.y+16) then hurtBad(v,i) v.vy=-2 end end end end end for i,v in pairs(bads) do if col(self.x,self.y+4,16,20,v.x,v.y,16,16) then if v.hurt then table.insert(scores,{x=v.x,y=v.y,t=t}) score=score+800 sfx(11) table.insert(deads,{x=v.x,y=v.y,spr=anis[v.type].dead[1],vx=(v.x-p.x)/16,vy=-2}) killed=killed+1 table.remove(bads,i) table.insert(coins,{x=32,y=32,vx=.5,vy=0}) if killed==(3+(phase%5))-1 then for i,v in pairs(bads) do v.state=3 end end else --PLAYER DEATH sfx(12) p.dead=true p.deathtime=t end end end if t%6==0 and (btn(2) or btn(3)) and self.vy==0 then sfx(6,36+step[self.stepid%8+1],3,1,3) self.stepid=self.stepid+1 end if (btn(2) or btn(3)) and (self.vx<=.01 and self.vx>=-.01) and self.vy==0 then sfx(10,"E-5",-1,2,10) local x=0 if btn(2) then x=16 end for i=0,4 do table.insert(parts,{x=p.x+x,y=p.y+22,vx=0,vy=0,t=0,c=15,s=1.5+rand(0,1)}) end end end self.x=self.x+self.vx self.x=self.x%(map_w) self.y=self.y+self.vy --self.spr=self.ani[(((t)//3)% #self.ani)+1] end init() local bids={"shell","crab","fly","ice"} local sp={{42,1},{27*8,-1}} function TIC() t=t+1 if t-phase_over<50 then return elseif t-phase_over==50 then advancePhase() end do local addr=0x03FF9 if t-shake_t<10 then poke(addr,rand(-2,2)) poke(addr+1,rand(-2,2)) else poke(addr,0) poke(addr+1,0) end end if state==0 then startScreen() elseif state==1 then if killed==3+(phase%5) then endPhase() return end if not pmusic() and t%300==0 and spawned<3+(phase%5) then local d=sp[rand(1,2)] table.insert(bads,{x=d[1],y=32,vx=.5,vy=0,dir=d[2],state=1,type=bids[rand(1,#bids)],t=t}) spawned=spawned+1 end cls(0) my=math.min(math.clamp(-88,68-p.y,0)) mx=math.min(math.clamp(-16,120-(p.x+8),0)) doBads() doCoins() --map(0,0,32,28,mx,my,0) dmap(0,0,32,28,mx,my+1,0,function(ot) --REMAP if ot==33 then ot=33+phase%3 end if ot==154 then ot=0 end return ot end) p:update() p:draw() doParts() for i,v in pairs(deads) do v.vy=v.vy+.1 v.x=v.x+v.vx v.y=v.y+v.vy spr(v.spr,v.x+mx,v.y+my,0,1,0,(t//6)%4,2,2) if v.y>map_h then table.remove(deads,i) end end fontc("PHASE "..phase,map_w/2+mx,map_h/2+my+20,15,true) doScores() for i=0,p.lives-1 do spr(16,i*12,10,0) end fontc("I-",2,0,13) fontc(score,16,0,15) local twidth=font(pmem(0),0,-32) local fwidth=font("TOP-",0,-32) fontc("TOP-",239-twidth-fwidth,0,9,false) fontc(pmem(0),239-twidth,0,15,false) --GAMEOVER STATE elseif state==2 then cls(0) fontc("GAME OVER",119,32,15,true) fontc("SCORE:",119,42,15,true) fontc(score,119,52,15,true) if score>pmem(0) then fontc("NEW HIGH SCORE!", 119,67,14,true) end fontc("PRESS A TO CONTINUE...",119,82,15,true) if btnp(4) then if score>pmem(0) then pmem(0,score) end init() end end --print(killed.."\n"..spawned.."\n"..(3+phase%5),32) end