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

Recent

Welcome to TinyPortal. Please login or sign up.

Recent posts

#21
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>
#22
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:
#23
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>
#24
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.

 ::)

#25
Block Codes / Re: Space invader game
Last post by Kernal - March 09, 2026, 07:29:25 PM
Ok fixed a few things on this code so this is a new update that works as a space invader game should do.


<div style="text-align:center;font-family:Arial;color:white;">
<h3>Space Invaders</h3>

<div id="highscore">High Score: 0 | Kernal Coded 2026 for TinyPortal</div>

<canvas id="game" width="320" height="400" style="background:black;border:3px solid #444;margin-top:10px;"></canvas>

<p>
⬅️ ➡️ Move &nbsp;&nbsp; SPACE = Fire &nbsp;&nbsp; R = Restart
</p>
</div>

<script>

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

let player = {x:150,y:360,width:20,height:10,speed:4};

let bullets = [];
let invaders = [];

let score = 0;
let level = 1;

let highScore = localStorage.getItem("tpInvaderHighScore") || 0;

let gameOver = false;
let exploding = false;
let explosionFrame = 0;

let keys = {};

let direction = 1;
let invaderSpeed = 1;

const invaderSprite = [
"00111100",
"11111111",
"11011011",
"11111111",
"00111100",
"01011010",
"10000001",
"01000010"
];

function updateHighScore(){

if(score > highScore){
highScore = score;
localStorage.setItem("tpInvaderHighScore", highScore);
}

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

}

updateHighScore();

function drawSprite(sprite,x,y,size,color){

ctx.fillStyle=color;

for(let r=0;r<sprite.length;r++){
for(let c=0;c<sprite[r].length;c++){

if(sprite[r][c]=="1"){
ctx.fillRect(x+c*size,y+r*size,size,size);
}

}
}

}

function createInvaders(){

invaders=[];

for(let r=0;r<4;r++){
for(let c=0;c<8;c++){

invaders.push({
x:40+c*30,
y:40+r*25,
alive:true
});

}
}

}

createInvaders();

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.width)
player.x = canvas.width-player.width;

}

function drawPlayer(){

if(exploding){
drawExplosion();
return;
}

ctx.fillStyle="lime";
ctx.fillRect(player.x,player.y,player.width,player.height);
ctx.fillRect(player.x+7,player.y-5,6,5);

}

function drawExplosion(){

ctx.fillStyle="orange";

for(let i=0;i<12;i++){

ctx.fillRect(
player.x + Math.random()*20,
player.y + Math.random()*15,
3,
3
);

}

explosionFrame++;

if(explosionFrame > 25){
gameOver = true;
}

}

function drawBullets(){

ctx.fillStyle="yellow";

bullets.forEach(b=>{
ctx.fillRect(b.x,b.y,3,10);
});

}

function drawInvaders(){

invaders.forEach(i=>{
if(i.alive){
drawSprite(invaderSprite,i.x,i.y,2,"white");
}
});

}

function moveInvaders(){

let hitEdge=false;

invaders.forEach(i=>{

if(!i.alive) return;

i.x += direction * invaderSpeed;

if(i.x < 10 || i.x > 280){
hitEdge=true;
}

});

if(hitEdge){

direction *= -1;

invaders.forEach(i=>{
i.y += 10;
});

}

}

function updateBullets(){

bullets.forEach(b=> b.y -= 6);

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;
updateHighScore();

}

});

});

bullets = bullets.filter(b=> b.y > 0);

}

function checkPlayerHit(){

invaders.forEach(i=>{
if(i.alive && i.y + 16 >= player.y){
exploding=true;
}
});

}

function checkWaveComplete(){

let alive = invaders.some(i=>i.alive);

if(!alive){

level++;
invaderSpeed += 0.4;

createInvaders();

}

}

function drawScore(){

ctx.fillStyle="white";
ctx.fillText("Score: "+score,10,15);
ctx.fillText("Level: "+level,250,15);

}

function drawGameOver(){

ctx.fillStyle="red";
ctx.font="20px Arial";
ctx.fillText("GAME OVER",100,200);

ctx.fillStyle="white";
ctx.font="14px Arial";
ctx.fillText("Press R to Restart",95,230);

}

function gameLoop(){

ctx.clearRect(0,0,canvas.width,canvas.height);

movePlayer();

drawPlayer();
drawBullets();
drawInvaders();
drawScore();

if(!exploding){

updateBullets();
moveInvaders();
checkPlayerHit();
checkWaveComplete();

}

if(gameOver){

drawGameOver();
return;

}

requestAnimationFrame(gameLoop);

}

document.addEventListener("keydown",e=>{

keys[e.key] = true;

if(e.key === " "){

bullets.push({
x:player.x+10,
y:player.y
});

}

if(e.key==="r" || e.key==="R"){
restartGame();
}

});

document.addEventListener("keyup",e=>{
keys[e.key] = false;
});

function restartGame(){

score=0;
level=1;
invaderSpeed=1;

bullets=[];

exploding=false;
explosionFrame=0;
gameOver=false;

createInvaders();

gameLoop();

}

gameLoop();

</script>
#26
Block Codes / Re: Space invader game
Last post by Kernal - March 09, 2026, 07:23:35 PM
Ok well thanks for all the add the invader graphic`s to the game so hey oh i did it anyway as tonight i`ve got lots of feel time on my coding fingers.....


So

Stage two of the Invaders game TP-Invaders!

<div style="text-align:center;font-family:Arial;color:white;">
<h3>Space Invaders</h3>

<div id="highscore">High Score: 0 | Kernal Coded 2026 for TinyPortal</div>

<canvas id="game" width="320" height="400" style="background:black;border:3px solid #444;margin-top:10px;"></canvas>

<p>
⬅️ ➡️ Move &nbsp;&nbsp; SPACE = Fire &nbsp;&nbsp; R = Restart
</p>
</div>

<script>

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

let player = {x:150,y:360,width:20,height:10,speed:4};

let bullets = [];
let invaders = [];

let score = 0;
let highScore = localStorage.getItem("tpInvaderHighScore") || 0;

let gameOver = false;
let exploding = false;
let explosionFrame = 0;

let keys = {};

const invaderSprite = [
"00111100",
"11111111",
"11011011",
"11111111",
"00111100",
"01011010",
"10000001",
"01000010"
];

function updateHighScore(){

if(score > highScore){
highScore = score;
localStorage.setItem("tpInvaderHighScore", highScore);
}

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

}

updateHighScore();

function drawSprite(sprite,x,y,size,color){

ctx.fillStyle=color;

for(let r=0;r<sprite.length;r++){
for(let c=0;c<sprite[r].length;c++){

if(sprite[r][c]=="1"){
ctx.fillRect(x+c*size,y+r*size,size,size);

}

}
}

}

function createInvaders(){

invaders=[];

for(let r=0;r<4;r++){
for(let c=0;c<8;c++){

invaders.push({
x:40+c*30,
y:40+r*25,
alive:true
});

}
}

}

createInvaders();

let direction = 1;

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.width) player.x = canvas.width - player.width;

}

function drawPlayer(){

if(exploding){
drawExplosion();
return;
}

ctx.fillStyle="lime";
ctx.fillRect(player.x,player.y,player.width,player.height);
ctx.fillRect(player.x+7,player.y-5,6,5);

}

function drawExplosion(){

ctx.fillStyle="orange";

for(let i=0;i<12;i++){

ctx.fillRect(
player.x + Math.random()*20,
player.y + Math.random()*15,
3,
3
);

}

explosionFrame++;

if(explosionFrame > 25){
gameOver = true;
}

}

function drawBullets(){

ctx.fillStyle="yellow";

bullets.forEach(b=>{
ctx.fillRect(b.x,b.y,3,10);
});

}

function drawInvaders(){

invaders.forEach(i=>{
if(i.alive){
drawSprite(invaderSprite,i.x,i.y,2,"white");
}
});

}

function moveInvaders(){

let hitEdge=false;

invaders.forEach(i=>{

if(!i.alive) return;

i.x += direction;

if(i.x < 10 || i.x > 280){
hitEdge = true;
}

});

if(hitEdge){

direction *= -1;

invaders.forEach(i=>{
i.y += 10;
});

}

}

function updateBullets(){

bullets.forEach(b=> b.y -= 5);

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;
updateHighScore();

}

});

});

bullets = bullets.filter(b=> b.y > 0);

}

function checkPlayerHit(){

invaders.forEach(i=>{

if(i.alive && i.y + 16 >= player.y){
exploding = true;
}

});

}

function drawScore(){

ctx.fillStyle="white";
ctx.fillText("Score: " + score,10,15);

}

function drawGameOver(){

ctx.fillStyle="red";
ctx.font="20px Arial";
ctx.fillText("GAME OVER",100,200);

ctx.fillStyle="white";
ctx.font="14px Arial";
ctx.fillText("Press R to Restart",95,230);

}

function gameLoop(){

ctx.clearRect(0,0,canvas.width,canvas.height);

movePlayer();

drawPlayer();
drawBullets();
drawInvaders();
drawScore();

if(!exploding){

updateBullets();
moveInvaders();
checkPlayerHit();

}

if(gameOver){

drawGameOver();
return;

}

requestAnimationFrame(gameLoop);

}

document.addEventListener("keydown",e=>{

keys[e.key] = true;

if(e.key === " "){

bullets.push({
x:player.x+10,
y:player.y
});

}

if(e.key==="r" || e.key==="R"){
restartGame();
}

});

document.addEventListener("keyup",e=>{
keys[e.key] = false;
});

function restartGame(){

score = 0;
bullets = [];

exploding = false;
explosionFrame = 0;
gameOver = false;

createInvaders();

gameLoop();

}

gameLoop();

</script>
#27
Chit chat / Re: Hog roast sausage`s tonigh...
Last post by Kernal - March 09, 2026, 06:44:59 PM
And here is river waiting for her share of MY hog roast hot dog  :2funny:  :2funny:
#28
Chit chat / Re: Hog roast sausage`s tonigh...
Last post by Kernal - March 09, 2026, 06:40:32 PM
Not sure why i wanted to post my hotdog but hey oh why not so here it is my hot dog ready to eat and ov course my Daughters dog is hanging around my legs for scraps  :2funny:

#29
Chit chat / Hog roast sausage`s tonight
Last post by Kernal - March 09, 2026, 06:25:06 PM
LMAO,....Yup that`s right i`m going to be testing out these sausage`s tonight HOG ROAST  :2funny:

So Monday night is my home alone night to do whatever i wish to do......So i thought Hmmmmmmmm Hog Roast sausages Hmmm, I seen them on the market stall and i thought YUP let have them should be interesting.

So they are in the oven and cooking away.......

I`ve also started to cook onions so instead of frying them I've decided to cook them in boiled water just like the old days when my mum took me to the fair and asked me do i want a hotdog  O0

They used to put boiled onions on there hotdogs too if i remember right!

Does anyone else remember this.....  :-\
#30
Chit chat / Re: What annoyed you today?
Last post by Kernal - March 09, 2026, 06:17:17 PM
Quote from: timberguy on February 28, 2026, 08:11:01 PMTrying to get logged in so I could message Lurksalot!I did at least get logged in. Password reminder would not send to me.

It`s Sir Lurkalot he`s been upgraded  :D  :2funny:

This website is proudly hosted on Crocweb Cloud Website Hosting.