Tag Archives: javascript

Mqtt Pong

This weekend we went to Nerdland in Belgium.
I saw a cool game when we had to wait before some talks started.

What is so special about pong?
Well, half of the audience was playing the other part of the audience.
250 against 250 Multiplayer.
It used mqtt websockets, and the audience mobile phones with tilting.
Average of 33+ % choosing up? Paddle goes up, Center and down the same.

I think I can make it myself.
So below my two days progression.
MQTT via internet.
Sound and score counter.
Using the mobile phone’s tilt sensor.

I changed left and right because we sat in the wrong chairs.

Maybe I’m going to change it into some 3D maze game.
Code soon

WSS Websocket to MQTT updating website

Using a mqtt server with websockets and a website with the Eclipse Paho JavaScript Client

Above video: Joystick sends movement through the internet to my mqtt server, laptop is fetching a webpage from one of my webservers.
A piece of javascript connects via websockets to the mqtt server and realtime changes the displayed image.

I intend to display maps and views into a maze you can walk through. like: (shamelessly stolen image from the internet)

I already have written another piece of code which generates a maze, and tells you using samples which way to go.

CODE

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title></title>
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
     <script type = "text/javascript" 
         src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script type = "text/javascript">
    var connected_flag=0    
    var mqtt;
    var reconnectTimeout = 2000;
    var host="MQTTSERVER";
    var port=8084;
var sub_topic="web/#";
    function onConnectionLost(){
    connected_flag=0;
			    document.getElementById("status").innerHTML = "Connection to HQ Lost";

    }
    function onFailure(message) {
        console.log("Failed");
        setTimeout(MQTTconnect, reconnectTimeout);
        }
    function onMessageArrived(r_message){
        var topic=r_message.destinationName;
			    document.getElementById("status").innerHTML = "";

        if(topic=="web/mapviewer")
        {
			    $(".deze").attr("src","tiles/" + r_message.payloadString + ".png");
        }
        }
    function onConnected(recon,url){
    console.log(" in onConnected " +reconn);
    }
    function onConnect() {
      // Once a connection has been made, make a subscription and send a message.
    connected_flag=1
			    document.getElementById("status").innerHTML = "Connection made to HQ";

    mqtt.subscribe(sub_topic);
      }

    function MQTTconnect() {

    console.log("connecting to "+ host +" "+ port);
    var x=Math.floor(Math.random() * 10000); 
    var cname="controlform-"+x;
    //var cname="escape1";
    mqtt = new Paho.MQTT.Client(host,port,cname);
    var options = {
	useSSL:true,
        timeout: 3,
        onSuccess: onConnect,
        onFailure: onFailure,
      
     };
    
        mqtt.onConnectionLost = onConnectionLost;
        mqtt.onMessageArrived = onMessageArrived;

    mqtt.connect(options);
    return false;
  
 
    }
    function sub_topics(){
        document.getElementById("messages").innerHTML ="";
        if (connected_flag==0){
        out_msg="<b>Not Connected so can't subscribe</b>"
        console.log(out_msg);
        document.getElementById("messages").innerHTML = out_msg;
        return false;
        }
    var stopic= document.forms["subs"]["Stopic"].value;
    console.log("Subscribing to topic ="+stopic);
    mqtt.subscribe(stopic);
    return false;
    }
    function send_message(msg,topic){
        if (connected_flag==0){
        out_msg="<b>Not Connected so can't send</b>"
        console.log(out_msg);
        document.getElementById("messages").innerHTML = out_msg;
        return false;
        }
        var value=msg.value;
        console.log("value= "+value);
        console.log("topic= "+topic);
        message = new Paho.MQTT.Message(value);
        message.destinationName = "web/"+topic;

        mqtt.send(message);
        return false;
    }

    
    </script>
<style>
@media only screen and (max-width: 600px) {
  div {
  max-width: 320px; 
  }
  
  img {
  max-width: 320px; 
  }
}
div.imageview {
  color: white;
  background: gray;
  padding: 15px;
  position: absolute;
  top: 50%;
  left: 50%;
  -ms-transform: translateX(-50%) translateY(-50%);
  -webkit-transform: translate(-50%,-50%);
  transform: translate(-50%,-50%);
}
</style>

  </head>
  <body onload="MQTTconnect()">
    

	  <div class=imageview>
<img class="deze" src="tiles/00.png"> 
<div id="status">Connection Status: Not Connected</div>

	  </div>
  </body>
</html>

Guess the code in Node Red

I asked ChatGPT to write code for me, i was not completely correct, and in Python. https://www.henriaanstoot.nl/2023/03/28/i-asked-chatgpt-to-write-code-for-a-crack-the-code-game/
I wrote my on version in JavaScript so it can be used in NodeRed as a function.

The codes are entered using a keypad (Arduino) and send via MQTT

Node Red Dash board

Code

var code = global.get("mysetcode");
var good = 0;
var wrong = 0;
var wrongplace = 0;
var match = false;
var wrongchars = 0;
var wrongplaced = 0;
var goodchars = 0;
var payloadcode = msg.payload.toString();

var usr_input = Array.from(payloadcode);
var secret_code = Array.from(code);
var secret_code1 = secret_code;

if (msg.payload === code) {
    match = true;
}
var result = "";

for (var i = 0; i < 4; i++) {
    var found = false;
    if (usr_input[i] === secret_code[i]) {
    usr_input[i] = "a";
    secret_code[i] = "b";
        good = good + 1;
        
    }
}

for (var i = 0; i < 4; i++) {
    var found = false;
    for (var j = 0; j < 4; j++) {
        if (usr_input[i] === secret_code[j]) {
                found = true;
        } 
    }
        if (!found) {
    wrong = wrong + 1;
    }
}

wrongchars = wrong - good;
wrongplaced = 4 - good - wrongchars;

msg.goodchars = good;
msg.wrongchars = wrongchars;
msg.wrongplace = wrongplaced;
msg.result = result;
msg.match = match;
return msg;

Escape game world generator

A world map generator in php.
This php script selects randomly 3 cities from a CSV file and draws these on a worldmap.
No cities wil be choosen which have could cause a drawing overlap.
Every player can see the same generated worldmap with a countdown timer.

CSV example with places and coordinates (cities.csv)

London,905,412
Amsterdam,929,414
Wellington,1722,867
Costa Rica,524,640
New Delhi,1270,514
New York,567,477
Tokio,1548,500

generate.html

<html><body bgcolor=black>
<header>
  <div class="menu_area"></div>
  <center>
<p id="demo" style="text:white;"></p>
  </center>
</header>
<style>
html, body, header {
    overflow: hidden; /* Hide scrollbars */
    height: 100%;
    text: white;
}
header {
    background-image: url('world.php');
    background-size: cover;
}
  p {
  color: white;
  font-size: large;
  font-family: Verdana, Arial, sans-serif;
  font-size: 42px;
 }
</style>
<script>
	Date.prototype.addHours= function(h){
    this.setHours(this.getHours()+h);
    return this;
}

var countDownDate = new Date().addHours(1).getTime();
  var x = setInterval(function() {
  var now = new Date().getTime();
  var distance = countDownDate - now;
  var days = Math.floor(distance / (1000 * 60 * 60 * 24));
  var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
  var seconds = Math.floor((distance % (1000 * 60)) / 1000);

  document.getElementById("demo").innerHTML = days + "d " + hours + "h "
  + minutes + "m " + seconds + "s ";

  if (distance < 0) {
    clearInterval(x);
    document.getElementById("demo").innerHTML = "EXPIRED";
  }
}, 1000);
</script>
</body></html>

Used world image to draw on.

The squares and city names are dynamically drawn using php GD lib.

apt-get install apache2 php php-gd

php example:

// create image from source
$src = imagecreatefromjpeg('world.jpg');
$dest = imagecreatetruecolor(1920, 1080);
// 1920x1080
imagecopy($dest, $src, 0, 0, 0,0, 1920, 1080);
// assign color
$white = imagecolorallocate($dest, 255, 255, 255);
// rectangle example
imagerectangle($dest, $x, $y, $x2, $y2, $white);
// add text
Imagettftext($dest, 24, 0, $x, $y, $white, $font, "Text");
// set header output as image
header('Content-Type: image/jpg');
// output to browser
imagejpeg($dest);
// output to file
imagejpeg($dest, 'generatedworld.jpg');
// Free memory
imagedestroy($dest);
imagedestroy($src);

world.php is included as image, it dynamically generates the map

<?php

putenv('GDFONTPATH=' . realpath('.'));

// Name the font to be used (note the lack of the .ttf extension)
$font = 'tahoma.ttf';
$city1="";
$city2="";
$city3="";

// Create image instances
$src = imagecreatefromjpeg('world.jpg');
$dest = imagecreatetruecolor(1920, 1080);

// Copy
imagecopy($dest, $src, 0, 0, 0,0, 1920, 1080);

$green = imagecolorallocate($dest, 255, 255, 255);



$rows = file("cities.csv");
$len = count($rows);
$rand = [];
while (count($rand) < 1) {
    $r = rand(0, $len-1);
    if (!in_array($r, $rand)) {
        $rand[] = $r;
    }
}
foreach ($rand as $r) {
    $csv = $rows[$r];
    $data = str_getcsv($csv);
    $city1="$data[0]";
    $x1=$data[1];
    $y1=$data[2];
}

imagerectangle($dest, $x1-50, $y1-50, $x1+50, $y1+50, $green);
imagerectangle($dest, $x1-49, $y1-49, $x1+49, $y1+49, $green);
imagerectangle($dest, $x1-10, $y1, $x1+10, $y1-1, $green);
imagerectangle($dest, $x1, $y1-10, $x1-1, $y1+10, $green);
Imagettftext($dest, 24, 0, $x1-50, $y1-60, $green, $font, "$city1");

while($city2 == "") {

$rows = file("cities.csv");
$len = count($rows);
$rand = [];
while (count($rand) < 1) {
    $r = rand(0, $len-1);
    if (!in_array($r, $rand)) {
        $rand[] = $r;
    }
}
foreach ($rand as $r) {
    $csv = $rows[$r];
    $data = str_getcsv($csv);
    $x2=$data[1];
    $y2=$data[2];
    $deltax=abs($x2-$x1);
    $deltay=abs($y2-$y1);
}
if($data[0] != $city1 && $deltax > 100 && $deltay > 100 ){
	$city2=$data[0];
}

}


imagerectangle($dest, $x2-50, $y2-50, $x2+50, $y2+50, $green);
imagerectangle($dest, $x2-49, $y2-49, $x2+49, $y2+49, $green);
imagerectangle($dest, $x2-10, $y2, $x2+10, $y2-1, $green);
imagerectangle($dest, $x2, $y2-10, $x2-1, $y2+10, $green);
Imagettftext($dest, 24, 0, $x2-50, $y2-60, $green, $font, "$city2");


while($city3 == "") {

$rows = file("cities.csv");
$len = count($rows);
$rand = [];
while (count($rand) < 1) {
    $r = rand(0, $len-1);
    if (!in_array($r, $rand)) {
        $rand[] = $r;
    }
}
foreach ($rand as $r) {
    $csv = $rows[$r];
    $data = str_getcsv($csv);
    $x3=$data[1];
    $y3=$data[2];
    $deltax=abs($x3-$x1);
    $deltay=abs($y3-$y1);
    $deltax1=abs($x3-$x2);
    $deltay1=abs($y3-$y2);
}
if($data[0] != $city1 && $data[0] != $city2 && $deltax > 100 && $deltay > 100 && $deltax1 > 100 && $deltay1 > 100 ){
	$city3=$data[0];
}
}
imagerectangle($dest, $x3-50, $y3-50, $x3+50, $y3+50, $green);
imagerectangle($dest, $x3-49, $y3-49, $x3+49, $y3+49, $green);
imagerectangle($dest, $x3-10, $y3, $x3+10, $y3-1, $green);
imagerectangle($dest, $x3, $y3-10, $x3-1, $y3+10, $green);
Imagettftext($dest, 24, 0, $x3-50, $y3-60, $green, $font, "$city3");


// Output and free from memory
header('Content-Type: image/jpg');
imagejpeg($dest);
imagejpeg($dest, 'generatedworld.jpg');


imagedestroy($dest);
imagedestroy($src);
?>