TP-Docs
HTML5 Icon HTML5 Icon HTML5 Icon
TP on Social Media

Recent

Welcome to TinyPortal. Please login or sign up.

Recent posts

#1
Chit chat / Re: OMG
Last post by lurkalot - Today at 01:34:13 AM
Look at the stats. It's not uncommon for the guest count to exceed 1642

Online ever: 8,223 (February 19, 2025

#2
Chit chat / Needs addressing this Lurk
Last post by Kernal - Today at 12:18:31 AM
 :)

#3
Chit chat / Re: OMG
Last post by Kernal - March 09, 2026, 10:46:15 PM
1642 Guests Wow   :knuppel2:
#4
Chit chat / OMG
Last post by Kernal - March 09, 2026, 10:45:11 PM
WOW.....
#5
Block Codes / Re: Space invader game
Last post by Kernal - March 09, 2026, 10:25:02 PM
I think this game is complete now and I'm going to end it right here so this is my code for Tiny portal Kernal coded in 2026 who even thought I'd be coding this long I'm a c64 & Zx spectrum coder...6510 & z80 chips......And here i am still coding...  :uglystupid2:


Anyway i do hope you all liked the coding with that simple space invader game was somewhat fun to do i think!.....

Take good care and have a good day

KeRnAl




#6
Block Codes / Re: Space invader game
Last post by Kernal - March 09, 2026, 09:58:39 PM
Last time i worked on a game was with Ocean software in Manchester squirting coded over a dial up phone  :2funny:
#7
Block Codes / Re: Space invader game
Last post by Kernal - March 09, 2026, 09:17:44 PM
 :)

So i changed the character`s to black text and well if your all following this code then it`s code in progress be fun to follow with all the upgrades to the game.

 :D <div style="text-align:center;color:#000066;font-family:monospace">
<h3>SPACE INVADERS</h3>
<div id="highscore">High Score: 0 | Kernal Coded 2026 for TinyPortal</div>
<canvas id="game" width="360" height="440"
style="background:black;border:6px solid #00ff66;box-shadow:0 0 30px #00ff66 inset;"></canvas>

<div style="margin-top:5px;">
  <button id="leftBtn" style="width:60px;height:40px;margin:5px;">⬅</button>
  <button id="fireBtn" style="width:60px;height:40px;margin:5px;">🔥</button>
  <button id="rightBtn" style="width:60px;height:40px;margin:5px;">➡</button>
</div>
<p>⬅ ➡ Move | SPACE Fire | R Restart</p>
</div>

<script>
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");

// Player
let player={x:170,y:400,w:24,h:12,speed:4,flash:0}
// Bullets
let bullets=[], enemyBullets=[]
// Invaders
let invaders=[]
// Shields
let shields=[]
// UFO
let ufo=null
let ufoScoreFlash=[]
// Game state
let level=1, score=0, direction=1, speed=0.6
let keys={}, lastShot=0, fireDelay=300
let highScore=localStorage.getItem("tpInvaderHighScore")||0
let gameOver=false

document.getElementById("highscore").innerHTML=
"High Score: "+highScore+" | Kernal Coded 2026 for TinyPortal"

// Starfield
const stars=[]
for(let i=0;i<80;i++) stars.push({x:Math.random()*360,y:Math.random()*440,r:Math.random()*2+1,speed:Math.random()*0.5+0.2})
function drawStars(){ ctx.fillStyle="white"; stars.forEach(s=>{ ctx.fillRect(s.x,s.y,s.r,s.r); s.y+=s.speed; if(s.y>440){s.y=0;s.x=Math.random()*360} }) }

// Sprites
const alienA1=["00111100","01111110","11011011","11111111","01111110","01000010"]
const alienA2=["00111100","01111110","11111111","11011011","11111111","00100100"]
const playerShip=["00100","01110","11111"]
const ufoSprite=["00111100","01111110","11111111","01111110"]

let marchStep=0, marchTimer=0, marchInterval=30
function drawSprite(sprite,x,y,s,c){
  ctx.fillStyle=c
  for(let r=0;r<sprite.length;r++)
    for(let d=0;d<sprite[r].length;d++)
      if(sprite[r][d]=="1") ctx.fillRect(x+d*s,y+r*s,s,s)
}

// Sounds
const audioCtx = new (window.AudioContext || window.webkitAudioContext)()
function playTone(freq,duration=0.1,volume=0.2){
  let osc=audioCtx.createOscillator()
  let gain=audioCtx.createGain()
  osc.connect(gain); gain.connect(audioCtx.destination)
  osc.type="square"; osc.frequency.value=freq
  gain.gain.value=volume
  osc.start()
  osc.stop(audioCtx.currentTime+duration)
}

// Explosions
let explosions=[]
function explosion(x,y){
  for(let i=0;i<8;i++) explosions.push({x:x+Math.random()*16,y:y+Math.random()*16,r:Math.random()*2+1,l:12,color:Math.random()>0.5?"yellow":"white"})
  playTone(600,0.1)
}

// Create invaders
function createInvaders(){
  invaders=[];
  for(let r=0;r<5;r++)
    for(let c=0;c<10;c++) invaders.push({x:40+c*28,y:50+r*26,alive:true,flash:0})
}
function drawInvaders(){
  invaders.forEach(i=>{
    if(!i.alive) return
    let sprite=(marchStep%2)?alienA1:alienA2
    if(i.flash>0){ ctx.fillStyle="white"; i.flash--; ctx.fillRect(i.x,i.y,16,16); return }
    drawSprite(sprite,i.x,i.y,2,"white")
  })
}

// Invader marching rhythm
function marchInvaders(){
  marchTimer++
  if(marchTimer>marchInterval){ marchTimer=0; marchStep=(marchStep+1)%4; playTone(100+marchStep*50,0.05) }
}

// Invader movement
function moveInvaders(){
  let edge=false;
  invaders.forEach(i=>{ if(!i.alive) return; i.x+=direction*speed; if(i.x<10||i.x>320) edge=true });
  if(edge){ direction*=-1; invaders.forEach(i=>i.y+=10); }
}

// Alien shooting
function alienShoot(){
  let alive=invaders.filter(i=>i.alive);
  if(alive.length && Math.random()<0.01*level){
    let s=alive[Math.floor(Math.random()*alive.length)];
    enemyBullets.push({x:s.x+8,y:s.y+12});
    playTone(400,0.05)
  }
}

// Shields
function createShields(){
  shields=[];
  for(let i=0;i<4;i++) shields.push({x:50+i*70,y:340,hp:30})
}
function drawShields(){
  ctx.fillStyle="#00ff66";
  shields.forEach(s=>{
    for(let i=0;i<s.hp;i++) ctx.fillRect(s.x+(i%6)*5,s.y+Math.floor(i/6)*5,4,4)
  })
}

// Player
function movePlayer(){
  if(keys["ArrowLeft"]||keys["TouchLeft"]) player.x-=player.speed;
  if(keys["ArrowRight"]||keys["TouchRight"]) player.x+=player.speed;
  if(player.x<0) player.x=0; if(player.x>canvas.width-player.w) player.x=canvas.width-player.w
}
function drawPlayer(){
  if(player.flash>0){ ctx.fillStyle="white"; ctx.fillRect(player.x-2,player.y-6,player.w+4,player.h); player.flash--; return }
  drawSprite(playerShip,player.x,player.y-6,4,"#00ff66");
}

// Bullets
function drawBullets(){ ctx.fillStyle="yellow"; bullets.forEach(b=>ctx.fillRect(b.x,b.y,3,10)); ctx.fillStyle="red"; enemyBullets.forEach(b=>ctx.fillRect(b.x,b.y,3,10)) }
function updateBullets(){
  bullets.forEach(b=>b.y-=6)
  enemyBullets.forEach(b=>b.y+=4)
  bullets.forEach(b=>{
    invaders.forEach(i=>{
      if(i.alive && b.x>i.x && b.x<i.x+16 && b.y>i.y && b.y<i.y+16){
        i.alive=false; i.flash=4; b.y=-100; score+=10; saveHigh(); explosion(i.x,i.y)
      }
    })
    shields.forEach(s=>{ if(s.hp>0 && b.x>s.x && b.x<s.x+30 && b.y>s.y && b.y<s.y+30){ s.hp-=1; b.y=-100 } })
  })
  enemyBullets.forEach(b=>{
    if(b.x>player.x && b.x<player.x+player.w && b.y>player.y){
      player.flash=6; explosion(player.x,player.y); gameOver=true; playTone(80,0.3)
    }
    shields.forEach(s=>{ if(s.hp>0 && b.x>s.x && b.x<s.x+30 && b.y>s.y && b.y<s.y+30){ s.hp-=1; b.y=-100 } })
  })
  bullets=bullets.filter(b=>b.y>0)
  enemyBullets=enemyBullets.filter(b=>b.y<440)
}

// Invaders hitting shields or base
function checkInvaderCollision(){
  let baseHit=false
  invaders.forEach(i=>{
    if(!i.alive) return;
    // Hit shields
    shields.forEach(s=>{
      if(s.hp>0 && i.y+16 >= s.y && i.x+16 > s.x && i.x < s.x+30){
        s.hp-=2; // invader destroys shield
        i.flash=4; // invader flashes
      }
    })
    // Hit player area
    if(i.y+16 >= player.y){
      // Check if shields already gone
      let shieldRemaining=shields.some(s=>s.hp>0)
      if(!shieldRemaining){
        baseHit=true;
        i.flash=4;
        player.flash=6;
        explosion(player.x,player.y);
        explosion(i.x,i.y);
      }
    }
  })
  if(baseHit) gameOver=true
}

// UFO
function spawnUFO(){ if(!ufo && Math.random()<0.003 + level*0.0005) ufo={x:-40,y:25,s:2} }
function updateUFO(){
  if(!ufo) return;
  ufo.x+=ufo.s;
  drawSprite(ufoSprite,ufo.x,ufo.y,2,"red");
  bullets.forEach(b=>{
    if(b.x>ufo.x && b.x<ufo.x+32 && b.y>ufo.y){
      score+=150;
      ufoScoreFlash.push({x:ufo.x,y:ufo.y-10,value:150,timer:20});
      ufo=null;
      playTone(700,0.15)
    }
  });
  if(ufo && ufo.x>380) ufo=null
}

// Draw UFO score flashes
function drawUfoScoreFlash(){
  ufoScoreFlash.forEach(f=>{
    ctx.fillStyle="yellow";
    ctx.font="14px monospace";
    ctx.fillText(f.value,f.x,f.y);
    f.timer--;
  });
  ufoScoreFlash=ufoScoreFlash.filter(f=>f.timer>0)
}

// Explosions
function drawExplosions(){
  explosions.forEach(e=>{ ctx.fillStyle=e.color; ctx.fillRect(e.x,e.y,e.r,e.r); e.l--; });
  explosions=explosions.filter(e=>e.l>0)
}

// Level / HUD
function checkWave(){ if(!invaders.some(i=>i.alive)){ level++; speed+=0.15 + level*0.05; createInvaders() } }
function hud(){ ctx.fillStyle="#00ff66"; ctx.fillText("Score "+score,10,20); ctx.fillText("Level "+level,290,20) }
function saveHigh(){ if(score>highScore){ highScore=score; localStorage.setItem("tpInvaderHighScore",highScore) }; document.getElementById("highscore").innerHTML="High Score: "+highScore+" | Kernal Coded 2026 for TinyPortal" }

// Game reset
function resetGame(){
  score=0; level=1; speed=0.6; bullets=[]; enemyBullets=[];
  createInvaders(); createShields(); ufo=null; gameOver=false;
  marchStep=0; marchTimer=0; ufoScoreFlash=[]; player.flash=0
}

// Game loop
function gameLoop(){
  ctx.clearRect(0,0,canvas.width,canvas.height)
  drawStars()
  if(gameOver) resetGame()
  marchInvaders()
  movePlayer(); drawPlayer(); drawInvaders(); drawBullets(); drawShields(); drawExplosions(); updateBullets()
  moveInvaders(); spawnUFO(); updateUFO(); drawUfoScoreFlash(); checkWave(); checkInvaderCollision()
  if(Math.random()<0.02) alienShoot()
  hud()
  requestAnimationFrame(gameLoop)
}

// Controls
document.addEventListener("keydown",e=>{
  keys[e.key]=true
  if(e.key===" "){ let now=Date.now(); if(now-lastShot>fireDelay && bullets.length<1){ bullets.push({x:player.x+11,y:player.y}); lastShot=now; playTone(800,0.05) } }
  if(e.key==="r"||e.key==="R") resetGame()
})
document.addEventListener("keyup",e=>keys[e.key]=false)

// Mobile buttons
document.getElementById("leftBtn").addEventListener("touchstart",()=>keys["TouchLeft"]=true)
document.getElementById("leftBtn").addEventListener("touchend",()=>keys["TouchLeft"]=false)
document.getElementById("rightBtn").addEventListener("touchstart",()=>keys["TouchRight"]=true)
document.getElementById("rightBtn").addEventListener("touchend",()=>keys["TouchRight"]=false)
document.getElementById("fireBtn").addEventListener("touchstart",()=>{
  let now=Date.now()
  if(now-lastShot>fireDelay && bullets.length<1){ bullets.push({x:player.x+11,y:player.y}); lastShot=now; playTone(800,0.05) }
})

// Init
createInvaders()
createShields()
gameLoop()
</script>
#8
Block Codes / Re: Space invader game
Last post by Kernal - March 09, 2026, 08:36:24 PM
So i`m thinking of adding rapid fire to the game and the space ship above well  :2funny: think it need`s a little graphics adding to it too... >:D

So this game can be added into your Tiny Portal block and it should work fine.

But still it`s work in progress any idea`s anyone that you would like added to the game,..

 :hmm:
#9
Block Codes / Re: Space invader game
Last post by Kernal - March 09, 2026, 08:03:47 PM
If i was honest i coded this game day`s ago to the point it is here  O0

TP-Invaders

<div style="text-align:center;color:#00ff66;font-family:monospace">
<h3>SPACE INVADERS</h3>
<div id="highscore">High Score: 0 | Kernal Coded 2026 for TinyPortal</div>
<canvas id="game" width="360" height="440"
style="background:black;border:6px solid #00ff66;box-shadow:0 0 30px #00ff66 inset;"></canvas>
<p>⬅ ➡ Move | SPACE Fire | R Restart</p>
</div>

<script>
const canvas = document.getElementById("game")
const ctx = canvas.getContext("2d")

// Player
let player={x:170,y:400,w:24,h:12,speed:4}
// Bullets
let bullets=[], enemyBullets=[]
// Invaders
let invaders=[]
// Shields
let shields=[]
// UFO
let ufo=null
// Game state
let level=1, score=0, direction=1, speed=0.6
let keys={}, lastShot=0, fireDelay=300
let highScore=localStorage.getItem("tpInvaderHighScore")||0
let gameOver=false

document.getElementById("highscore").innerHTML=
"High Score: "+highScore+" | Kernal Coded 2026 for TinyPortal"

// Starfield background
const stars=[]
for(let i=0;i<80;i++) stars.push({x:Math.random()*360,y:Math.random()*440,r:Math.random()*2+1,speed:Math.random()*0.5+0.2})
function drawStars(){ ctx.fillStyle="white"; stars.forEach(s=>{ ctx.fillRect(s.x,s.y,s.r,s.r); s.y+=s.speed; if(s.y>440){s.y=0;s.x=Math.random()*360} }) }

// Sprites
const alienA1=["00111100","01111110","11011011","11111111","01111110","01000010"]
const alienA2=["00111100","01111110","11111111","11011011","11111111","00100100"]
let animFrame=0

function drawSprite(sprite,x,y,s,c){
  ctx.fillStyle=c
  for(let r=0;r<sprite.length;r++)
    for(let d=0;d<sprite[r].length;d++)
      if(sprite[r][d]=="1") ctx.fillRect(x+d*s,y+r*s,s,s)
}

// Sound helpers
const audioCtx = new (window.AudioContext || window.webkitAudioContext)()
function playTone(freq,duration=0.1,volume=0.2){
  let osc=audioCtx.createOscillator()
  let gain=audioCtx.createGain()
  osc.connect(gain); gain.connect(audioCtx.destination)
  osc.type="square"; osc.frequency.value=freq
  gain.gain.value=volume
  osc.start()
  osc.stop(audioCtx.currentTime+duration)
}

// Explosions
let explosions=[]
function explosion(x,y){
  for(let i=0;i<5;i++) explosions.push({x:x+Math.random()*16,y:y+Math.random()*16,r:Math.random()*2+1,l:10})
  playTone(100+Math.random()*300,0.1)
}

// Invaders
function createInvaders(){ invaders=[]; for(let r=0;r<5;r++) for(let c=0;c<10;c++) invaders.push({x:40+c*28,y:50+r*26,alive:true}) }
function drawInvaders(){ invaders.forEach(i=>{ if(!i.alive) return; let sprite=animFrame?alienA1:alienA2; drawSprite(sprite,i.x,i.y,2,"white") }) }
function moveInvaders(){ let edge=false; invaders.forEach(i=>{ if(!i.alive) return; i.x+=direction*speed; if(i.x<10||i.x>320) edge=true }); if(edge){ direction*=-1; invaders.forEach(i=>i.y+=10) } }
function alienShoot(){ let alive=invaders.filter(i=>i.alive); if(alive.length){ let s=alive[Math.floor(Math.random()*alive.length)]; enemyBullets.push({x:s.x+8,y:s.y+12}); playTone(400,0.05) } }

// Shields
function createShields(){ shields=[]; for(let i=0;i<4;i++) shields.push({x:50+i*70,y:340,hp:30}) }
function drawShields(){ ctx.fillStyle="#00ff66"; shields.forEach(s=>{for(let i=0;i<s.hp;i++) ctx.fillRect(s.x+(i%6)*5,s.y+Math.floor(i/6)*5,4,4)}) }

// Player
function movePlayer(){ if(keys["ArrowLeft"]) player.x-=player.speed; if(keys["ArrowRight"]) player.x+=player.speed; if(player.x<0) player.x=0; if(player.x>canvas.width-player.w) player.x=canvas.width-player.w }
function drawPlayer(){ ctx.fillStyle="#00ff66"; ctx.fillRect(player.x,player.y,player.w,player.h); ctx.fillRect(player.x+9,player.y-6,6,6) }

// Bullets
function drawBullets(){ ctx.fillStyle="yellow"; bullets.forEach(b=>ctx.fillRect(b.x,b.y,3,10)); ctx.fillStyle="red"; enemyBullets.forEach(b=>ctx.fillRect(b.x,b.y,3,10)) }
function updateBullets(){
  bullets.forEach(b=>b.y-=6)
  enemyBullets.forEach(b=>b.y+=4)
  // Player bullets hit invaders or shields
  bullets.forEach(b=>{
    invaders.forEach(i=>{ if(i.alive && b.x>i.x && b.x<i.x+16 && b.y>i.y && b.y<i.y+16){ i.alive=false; b.y=-100; score+=10; saveHigh(); explosion(i.x,i.y) } })
    shields.forEach(s=>{ if(s.hp>0 && b.x>s.x && b.x<s.x+30 && b.y>s.y && b.y<s.y+30){ s.hp-=1; b.y=-100 } })
  })
  // Enemy bullets hit player or shields
  enemyBullets.forEach(b=>{
    if(b.x>player.x && b.x<player.x+player.w && b.y>player.y){ explosion(player.x,player.y); gameOver=true; playTone(50,0.3) }
    shields.forEach(s=>{ if(s.hp>0 && b.x>s.x && b.x<s.x+30 && b.y>s.y && b.y<s.y+30){ s.hp-=1; b.y=-100 } })
  })
  bullets=bullets.filter(b=>b.y>0)
  enemyBullets=enemyBullets.filter(b=>b.y<440)
}

// UFO
function spawnUFO(){ if(!ufo && Math.random()<0.003) ufo={x:-40,y:25,s:2} }
function updateUFO(){ if(!ufo) return; ufo.x+=ufo.s; ctx.fillStyle="red"; ctx.fillRect(ufo.x,ufo.y,30,12); bullets.forEach(b=>{ if(b.x>ufo.x && b.x<ufo.x+30 && b.y>ufo.y){ score+=150; ufo=null; playTone(600,0.1) } }); if(ufo && ufo.x>380) ufo=null }

// Explosions
function drawExplosions(){ ctx.fillStyle="orange"; explosions.forEach(e=>ctx.fillRect(e.x,e.y,e.r,e.r)); explosions.forEach(e=>e.l--); explosions=explosions.filter(e=>e.l>0) }

// Level / HUD
function checkWave(){ if(!invaders.some(i=>i.alive)){ level++; speed+=0.25; createInvaders() } }
function hud(){ ctx.fillStyle="#00ff66"; ctx.fillText("Score "+score,10,20); ctx.fillText("Level "+level,290,20) }
function saveHigh(){ if(score>highScore){ highScore=score; localStorage.setItem("tpInvaderHighScore",highScore) }; document.getElementById("highscore").innerHTML="High Score: "+highScore+" | Kernal Coded 2026 for TinyPortal" }

// Game reset
function resetGame(){ score=0; level=1; speed=0.6; bullets=[]; enemyBullets=[]; createInvaders(); createShields(); ufo=null; gameOver=false }

// Game loop
function gameLoop(){
  ctx.clearRect(0,0,canvas.width,canvas.height)
  drawStars()
  if(gameOver) resetGame()
  animFrame^=1
  movePlayer()
  drawPlayer()
  drawInvaders()
  drawBullets()
  drawShields()
  drawExplosions()
  updateBullets()
  moveInvaders()
  spawnUFO()
  updateUFO()
  checkWave()
  if(Math.random()<0.02) alienShoot()
  hud()
  requestAnimationFrame(gameLoop)
}

// Controls
document.addEventListener("keydown",e=>{
  keys[e.key]=true
  if(e.key===" "){ let now=Date.now(); if(now-lastShot>fireDelay && bullets.length<1){ bullets.push({x:player.x+11,y:player.y}); lastShot=now; playTone(800,0.05) } }
  if(e.key==="r"||e.key==="R") resetGame()
})
document.addEventListener("keyup",e=>keys[e.key]=false)

// Init
createInvaders()
createShields()
gameLoop()
</script>
#10
Block Codes / Re: Space invader game
Last post by Kernal - March 09, 2026, 07:41:37 PM
So as you can see on this space invader game that I'm developing on here we now have graphical invaders,...If you follow the code you`ll see that i coded the invader`s in binary as a sprite as they should be coded.

All the code here is Tiny Portal Block compatible and i think Lurk will be testing the code as i go to make sure it`s fine for your TP blocks....


So next step i think is adding barriers and a nice star field behind the invaders.

 ::)

This website is proudly hosted on Crocweb Cloud Website Hosting.