0 5€€ @UџџЊџЭuЇ№p8Зd%qy)6oЪЎAІіsяїєєє”АТVl†3 pmem(idx) then if idx < 4 then pmem(idx+1,pmem(idx)) pmem(idx+6,pmem(idx+5)) end pmem(idx,score) pmem(idx+5,model) else return idx+1 end if idx > 0 then return set_max_score(score,model, idx-1) else return 0 end end function reset_max_score() for i = 0,9 do pmem(i,0) end end --ship methods-------------------------------------- function tic(self,mv) if mv==nil then mv = true end --manage state if (self.state==1 or self.state==3) and self.t>=60 then self.t=0 self.state=2 end if self.state==4 and self.t>=30 then self.t=0 self.state=0 end if self.state~=0 and self.state~=4 then if mv then self:move() end self:draw() elseif self.state==4 then self:explode() end --time count self.t=self.t+1 if self.ammo < 100 then self.ammo = self.ammo + self.sht_chrg end end function set_model(self) self.spd=models[self.model+1].spd self.hp=models[self.model+1].hp self.sht_pwr=models[self.model+1].sht_pwr self.sht_rng=models[self.model+1].sht_rng self.sht_chrg=models[self.model+1].sht_chrg self.mini=models[self.model+1].mini if self.player==2 then self.mini=self.mini+8 end end function set_sprite(self) if self.state==1 then sprite_mod=size_dif*(2-(self.t//20)) else sprite_mod=0 end if self.player==2 then sprite_mod=sprite_mod+192 end bs_sprite=544+sprite_mod bs_model=4*self.model bs_direction=(self.direction%2)*2 self.sprite=bs_sprite+bs_model+bs_direction self.rotate=self.direction//2 end function set_direction(self,turn) self.x=(self.x//10)*10 self.y=(self.y//10)*10 if turn then self.direction=turn end self.dx=mv[self.direction+1].dx self.dy=mv[self.direction+1].dy self:set_sprite() end function draw(self) self:set_sprite() self:draw_shot() if (self.state>0 and self.state<3) or (self.state==3 and self.t%2==0) then spr(self.sprite,(self.x+5)//10,(self.y+5)//10,3,1,0,self.rotate,2,2) end end function border_bounce(self) if (self.x//10)<0 then if self.direction==5 then self:set_direction(3) end if self.direction==6 then self:set_direction(2) end if self.direction==7 then self:set_direction(1) end --self:hit(1) end if (self.x//10)>scr_w-16 then if self.direction==3 then self:set_direction(5) end if self.direction==2 then self:set_direction(6) end if self.direction==1 then self:set_direction(7) end --self:hit(1) end if (self.y//10)scr_h-16 then if self.direction==5 then self:set_direction(7) end if self.direction==4 then self:set_direction(0) end if self.direction==3 then self:set_direction(1) end --self:hit(1) end end function move(self) self.x=self.x+(self.dx*self.spd*speed_modifier) self.y=self.y+(self.dy*self.spd*speed_modifier) self:border_bounce() end function turn(self,rate) self:set_direction((self.direction+rate)%8) end function hit(self,dmg) if self.state==2 then self.t=0 if self.hp>0 then self.hp=self.hp-dmg end if self.hp>0 then sfx(33) self.state=3 return self.hp else sfx(34) self.state=4 self.shot.x=nil self.shot.y=nil self.shot.initial.x=nil self.shot.initial.y=nil self.shot.dx=nil self.shot.dy=nil self.shot.t=0 if self.player==2 then points=points+round_points round_points=round_points_max round=round+1 speed_modifier=ini_speed_modifier+((round//5)/10) point_discount=0 end return 0 end end return false end function explode(self) if (self.t//2)%3==0 then circb((self.x//10)+8,(self.y//10)+8,self.t,3) end xv=math.random(0,16) yv=math.random(0,16) rv=math.random(2,6) circ((self.x//10)+xv,(self.y//10)+yv,rv,3) end function shoot(self) if self.ammo>=100 then sfx(32) self.ammo=0 self.shot.initial.x=self.x+80+8*self.dx self.shot.initial.y=self.y+80+8*self.dy self.shot.x=self.shot.initial.x self.shot.y=self.shot.initial.y self.shot.dx=mv[self.direction+1].dx*3 self.shot.dy=mv[self.direction+1].dy*3 end end function draw_shot(self) if self.shot.x~=nil and self.shot.y~=nil then circ(self.shot.x//10,self.shot.y//10,2,0) circ(self.shot.x//10,self.shot.y//10,1,3) for i = 1,2,1 do tail_x=self.shot.x-(self.shot.dx*i) tail_y=self.shot.y-(self.shot.dy*i) circ(tail_x//10,tail_y//10,1,3) end self.shot.x=self.shot.x+(self.shot.dx*speed_modifier) self.shot.y=self.shot.y+(self.shot.dy*speed_modifier) self.shot.t=self.shot.t+1 end --if self.shot.t>=20*self.sht_rng/speed_modifier then if self.shot.x ~= nil and distance(self.shot,self.shot.initial) >= self.sht_rng*500 then self.shot.x=nil self.shot.y=nil self.shot.initial.x=nil self.shot.initial.y=nil self.shot.dx=nil self.shot.dy=nil self.shot.t=0 end end --ship factory------------------------ function shp(model,player,x,y,direction) new_shp={ t=0, x=x or 1200, y=y or 680, model=model or 0, --0 to 3 direction=direction or 0, --0 to 7 player=player or 1, ammo=100, state=1, --0:none;1:rising;2:flying;3:hit,4:destroyed -- model params -- spd, hp, sht_pwr, sht_spd, handling shot={ x=nil, y=nil, dx=nil, dy=nil, t=0, initial={ x=nil, y=nil } }, tic=tic, set_model=set_model, set_sprite=set_sprite, set_direction=set_direction, draw=draw, move=move, turn=turn, border_bounce=border_bounce, hit=hit, explode=explode, shoot=shoot, draw_shot=draw_shot } new_shp:set_model() new_shp:set_direction() return new_shp end --UI functions------------------------------------------ function print_border() rectb(0,top_bar,scr_w,scr_h-top_bar,12) end function print_lifes(ship,x) x=x or 0 for i = 0,ship.hp-1,1 do spr(ship.mini,(9*i)+x,0) end end function print_ammo_bar(ship,x) x=x or 0 rectb(x,1,29,8,12) rect(x+2,3,ship.ammo//4,4,ship.player) if ship.ammo >=100 then spr(929+ship.player,x+31,1) end end function print_points(x,y) x=x or 0 y=y or 0 spr(932,x,y,0,1,0,0,2,1) print(points,x+18,y+2,12) end function print_player_ui(ship,x) x=x or 0 print_lifes(ship,x) print_ammo_bar(ship,x+55) end function print_ui(p1,p2) rect(0,0,scr_w,top_bar,0) print_border() print_player_ui(p1) if p2 then print_player_ui(p2,96) end print_points(192,2) end function print_ship_selector(model,x,y,active,mini_select,spin_rate) active=active or false mini_select=mini_select or 608 spin_rate=spin_rate or 10 if active then rectb(x+(model*16),y,16,16,3) rectb(x+2+(model*16),y,12,16,0) end for i=0,3,1 do if i==model and active then spr(mini_select+2*((t//spin_rate)%2)+i*4,x+(i*16),y,3,1,0,(t//(spin_rate*2))%4,2,2) else spr(mini_select+i*4,x+(i*16),y,3,1,0,0,2,2) end end end function print_showcase(model,x,y) shp_select=540 --ship showcase----------------------------------- rectb(x,y-2,32,32,3) spr(shp_select+model*4,x+8,y+8,3,1,0,0,2,2) --stats------------------------------------------- selected=models[model] print("Speed:",x+34,y,1) rect(x+104,y,38*selected.spd,5,3) print("HP:",x+34,y+6,1) rect(x+104,y+6,15*(selected.hp//2),5,3) print("Shot Power:",x+34,y+12,1) rect(x+104,y+12,15*selected.sht_pwr,5,3) print("Shot Range:",x+34,y+18,1) rect(x+104,y+18,15*selected.sht_rng,5,3) print("Recharge:",x+34,y+24,1) rect(x+104,y+24,15*selected.sht_chrg,5,3) end function print_color_selector(color_idx,x,y,active) if color_idx==0 then color_idx=12 end active=active or false for i = 1,#colors do if i==color_idx and active then rectb(x-2+((i-1)*16),y-2,16,16,3) rectb(x+((i-1)*16),y-2,12,16,0) end rect(x+((i-1)*16),y,12,12,1) if i>=10 then num_pos=x+1+((i-1)*16) else num_pos=x+4+((i-1)*16) end print(i,num_pos,y+4,0) end end function change_color(hex,player) player=player or 1 addr= 0x3FC3 + (3*(player-1)) for i = 1,5,2 do pigment=tonumber(hex:sub(i,i+1),16) poke(addr+((i-1)/2),pigment) end end --Colision functions------------------------------------- function check_laser_hit(shooter,target) if shooter.shot.x>=target.x and shooter.shot.x<=target.x+160 and shooter.shot.y>=target.y and shooter.shot.y<=target.y+160 then target:hit(shooter.sht_pwr) shooter.shot.x=nil shooter.shot.y=nil shooter.shot.dx=nil shooter.shot.dy=nil shooter.shot.t=0 return true end return false end function check_ship_collision(ship1, ship2) if ship1.state==2 and ship2.state==2 then if ship1.x>=ship2.x-100 and ship1.x<=ship2.x+100 and ship1.y>=ship2.y-100 and ship1.y<=ship2.y+100 then ship1:hit(2) ship2:hit(2) return true end end return false end --Debug functions---------------------------------------- function debug(e) for i=1,#e do print(e[i],2,top_bar+2+(8*(i-1)),12) end end function show_grid(color,blink) color=color or 15 blink=blink or 1 if t%blink==0 then rectb(0,0,scr_w,scr_h,color) for i = 0,6 do rectb(i*(scr_w//6),0,1,scr_h,color) print(i*(scr_w//6),i*(scr_w//6)+2,2,color) for j = 0,scr_w,10 do rectb(i*(scr_w//6)+1,j,1,1,color) end end for i = 0,4 do rectb(0,i*(scr_h//4),scr_w,1,color) print(i*(scr_h//4),2,i*(scr_h//4)+2,color) for j = 0,scr_w,10 do rectb(j,i*(scr_h//4)+1,1,1,color) end end end end function game_reset() --demo=shp(math.random(0,3),1,50,100,1) demo=shp(3,1,500,1000,1) demo.spd=1 step=0 points=0 a_sel='model' color_id=math.random(1,12) enemy_color_id=(color_id+6)%#colors if enemy_color_id==0 then enemy_color_id=12 end t=0 change_color(colors[color_id]) change_color('204055',2) music(0) end game_reset() function TIC() if step == 99 then --Testing Features------------------ cls(0) show_grid() if t1==nil then t1=shp(0,1,400,400,2) t1.state=2 t1:set_sprite() end t1:tic(false) if btnp(4) then t1.x = t1.x+t1.dx t1.y = t1.y+t1.dy end if btnp(2,0,10) then t1:turn(-1) end if btnp(3,0,10) then t1:turn(1) end if btnp(5) then trace(60.0//10) trace(60.1//10) end debug({t1.x,t1.y, (t1.x+5)//10,(t1.y+5)//10, (t1.x+5)//10-(t1.y+5)//10}) elseif step==0 then --Title Screen------------------- cls(0) map(30,0) demo:tic() map(60,7,30,6,0,40,0) --show_grid() if (t//30)%2==0 then print("Press Z to start!",60,95,12) end if btnp(4) then t=0 speed_modifier=ini_speed_modifier round=1 step=1 end elseif step==1 then --Ship Select------------------- col_x=26 col_y=110 sel_x=88 sel_y=40 stats_x=sel_x-40 stats_y=sel_y+20 change_color(colors[enemy_color_id],2) cls(0) --show_grid() --miniature selector----------------------------- print("SELECT SPACESHIP MODEL:",sel_x-32,sel_y-10,12) print_ship_selector(ship,sel_x,sel_y,a_sel=="model") --color selector--------------------------------- print("SELECT SPACESHIP COLOR:",col_x+31,col_y-10,12) print_color_selector(color_id,col_x,col_y,a_sel=="color") --ship showcase----------------------------------- print_showcase(ship+1,stats_x,stats_y) --control----------------------------------------- --debug({color_id,enemy_color_id}) if btn(0) then a_sel="model" end if btn(1) then a_sel="color" end if a_sel=='model' then if btnp(2,0,40) then ship=(ship-1)%4; t=0 end if btnp(3,0,40) then ship=(ship+1)%4; t=0 end elseif a_sel=='color' then if btnp(2,0,40) then color_id=(color_id-1)%#colors enemy_color_id=(color_id+6)%#colors if color_id==0 then color_id=#colors end if enemy_color_id==0 then enemy_color_id=#colors end change_color(colors[color_id]) change_color(colors[enemy_color_id],2) end if btnp(3,0,40) then color_id=(color_id+1)%#colors enemy_color_id=(color_id+6)%#colors if color_id==0 then color_id=#colors end if enemy_color_id==0 then enemy_color_id=#colors end change_color(colors[color_id]) change_color(colors[enemy_color_id],2) end end if btnp(4) then if a_sel=="model" then a_sel="color" else hero=shp(ship) hero:set_sprite() enemy=shp(0,2) enemy:set_sprite() enemy.state=0 enemy.hp=0 t=0 step=2 end end elseif step==2 or step==3 then -----------Game--------------- if step==2 then if btnp(4) then hero:shoot() end --if btnp(5) then hero:hit(1) end if btnp(2,0,10) then hero:turn(-1) end if btnp(3,0,10) then hero:turn(1) end end --------------- cls(0) map() debug({}) if enemy.state == 0 and step==2 and t>60 and math.random(1,60)==1 then if (hero.x//10) > scr_w//2 then rand_x = math.random(16,scr_w//2) else rand_x = math.random(scr_w//2,scr_w-16) end if (hero.y//10) > scr_h//2 then rand_y = math.random(16,scr_h//2) else rand_y = math.random(scr_h//2,scr_h-16) end enemy=shp(math.random(0,3),2,rand_x*10,rand_y*10,math.random(0,7)) enemy:set_sprite() end if hero.shot.x and hero.shot.y then --debug({hero.x,hero.y}) if check_laser_hit(hero,enemy) then points = points+25 end end if enemy.state==2 and math.random(1,50)==1 then enemy:shoot() end if enemy.state==2 --and enemy.t==60*2 then and math.random(1,100)==1 then enemy:turn(math.random(-1,1)) end if enemy.shot.x and enemy.shot.y then check_laser_hit(enemy,hero) end check_ship_collision(hero,enemy) print_ui(hero,enemy) --show_grid(12,2) hero:tic() enemy:tic() point_discount=point_discount+1 if round_points >= round_points_min then round_points=round_points_max-(point_discount//60) end if hero.hp<=0 and step==2 then score_id=set_max_score(points,hero.model) --demo=shp(math.random(0,3),1,50,100,1) --demo.speed=1 step=3 t=0 end if step==3 then -----------Game Over---------- --show_grid() print("Game Over",70,15,2,true,2) print("YOUR SCORE",92,35,12) print(points,92,45,12) if score_id==0 then if (t//10)%2==0 then rect(81,52,80,10,12) print("New Record!!!",88,54,0) else print("New Record!!!",88,54,12) end end print("TOP SCORES",92, 65, 12) for i = 0,4 do if pmem(i)>0 then if i~=score_id or (t//20)%2==0 then print((i+1)..": "..pmem(i),92,75+(10*i), 12) spr(512+(pmem(i+5)*2),150,75+(10*i),0) end end end if btnp(4) and t>120 then game_reset() end end end debug({ --pmem(0).."-"..pmem(5), --pmem(1).."-"..pmem(6), --pmem(2).."-"..pmem(7), --pmem(3).."-"..pmem(8), --pmem(4).."-"..pmem(9) }) t=t+1 end