ANSI escape codes not moving cursor horizontally - javascript

I am trying to make a text editor in the terminal with node and typescript but the ansi escape codes aren't moving the cursor horizontally. THe cursor moves vertically correctly but it just wont move horizontally.
Code: (index.ts)
var width = process.stdout.columns;
var height = process.stdout.rows;
function dupe(input: string, length: number) {
var newI = ''
for (var i = 0; i < length; i++) {
newI += input
}
return newI
}
function pad(pad: string, input: string, width: number): string {
var space = ''
for (var i = 0; i < width - input.length; i++) {
space += pad
}
return input + space;
}
var stdin = process.stdin;
// without this, we would only get streams once enter is pressed
stdin.setRawMode( true );
// resume stdin in the parent process (node app won't quit all by itself
// unless an error or process.exit() happens)
stdin.resume();
// i don't want binary, do you?
stdin.setEncoding( 'utf8' );
// on any data into stdin
stdin.on( 'data', function( key ){
// ctrl-c ( end of text )
if ( key.toString() === '\u0003' ) {
process.exit();
}
// write the key to stdout all normal like
update(key.toString())
});
function setpos(x: number, y: number) {
return `\x1b[H\x1b[${y}B\x1b[${x}C`
}
var mousex = 0;
var mousey = 0;
async function update(key: string) {
key = key.toLowerCase();
width = process.stdout.columns;
height = process.stdout.rows;
console.clear()
console.log(dupe('-', width))
for ( var i = 1; i <= height-2; i++ ) {
process.stdout.write(`${pad(' ', i.toString(), 3)}|This is a test string\n`)
}
if (key === 'w') { mousey --;}
if (key === 's') { mousey ++;}
if (key === 'a') { mousex --;}
if (key === 'd') { mousex ++;}
if (mousey < 0) { mousey = 0}
if (mousey > height) { mousey = height}
if (mousex < 0) { mousex = 0 }
if (mousex > width) { mousex = width}
console.log(setpos(mousex, mousey))
console.log(`\x1b[1A${mousex} ${mousey} ${width} ${height}`)
}
update('')
stack overflow why do i need to write more i literally have nothing else to write.

Nevermind I was just dumb and didn't just try a different package.
Installing terminal-kit fixed my problem.

Related

Despite using an array for keydown (or keyup) functions my code still refuses to let me move while jumping

My code is as follows:
var map = [];
document.body.onkeydown = document.body.onkeyup = function(e){
e = e || event; // to deal with IE
map[e.key] = e.type == 'keydown';
console.log(map)
if (map["ArrowLeft"]) {move("left")}
if (map["ArrowRight"]) {move("right")}
if (map["Spacebar"] || map[" "]) {jump()};
However if i hold down the right arrow key and then press space the character jumps without changing the x pos.
My jumping code is:
async function jump() {
var jh = j;
var i;
for (i = jh * 2; i > -Math.abs(jh) * 2 - 0.5; i -= 0.5) {
rem_rect(70, py, 30, 30)
py -= i
rect(70, py, 30, 30)
await sleep(15)
}
}
My moving code is:
async function move(d) {
var i;
for (i = 0; i < p.length; i++) {
if (d === "right") {
var j;
for (j = 0; j <= 5; j++) {
rem_rect(p[i][0], p[i][1], p[i][2], p[i][3]);
p[i][0] -= ms / 5;
rect(p[i][0], p[i][1], p[i][2], p[i][3])
await sleep(0)
}
}
else if (d === "left") {
var j;
for (j = 0; j <= 5; j++) {
rem_rect(p[i][0], p[i][1], p[i][2], p[i][3]);
p[i][0] += ms / 5;
rect(p[i][0], p[i][1], p[i][2], p[i][3])
await sleep(0)
}
}
}
}

Checking if two points are touching in a hex grid

Some time ago I wrote this fun grid that is offset to look like a hexagonal grid. I added a feature to check if any two points are touching. I thought it was brilliant until I finally found a bug and am not sure how to correct it.
If you press (1,4) and (2,5) you will see that they are "touching" but they shouldn't be. What logic am I missing in the function isTouchingHex?
Found bugs so far..
(1,4) & (2,5)
(2,2) & (3,3)
(0,0) & (1,1)
CodePen
var $point1 = $('#point1');
var $point2 = $('#point2');
var $dx = $('#dx');
var $dy = $('#dy');
var $isTouching = $('#isTouching');
var $table = $('#hexTable');
var table = [];
var rows = 10;
var cols = 5;
var point1 = null;
var point2 = null;
var clickedCount = 0;
for (let y = 0; y < rows; y++) {
var $tr = $('<div class="hexagonRow"></div>')
var row = [];
for (let x = 0; x < cols; x++) {
var $col = $('<div class="hexagon"><div class="hexagonText">' + x + ',' + y + '</div></div>');
$col.click(function() {
if (clickPoint(x, y))
$(this).toggleClass('clicked');
});
$tr.append($col);
row.push(y);
}
$table.append($tr);
table.push(row);
}
function clickPoint(x, y) {
var clicked = true;
if (point1 && point1[0] === x && point1[1] === y) {
point1 = null;
clickedCount--;
} else if (point2 && point2[0] === x && point2[1] === y) {
point2 = null;
clickedCount--;
} else if (!point1 && clickedCount < 3) {
point1 = [x, y];
clickedCount++;
} else if (!point2 && clickedCount < 3) {
point2 = [x, y];
clickedCount++;
} else {
clicked = false;
}
updateDisplay();
return clicked;
}
function updateDisplay() {
if (point1)
$point1.html(point1[0] + ',' + point1[1])
else
$point1.html('');
if (point2)
$point2.html(point2[0] + ',' + point2[1])
else
$point2.html('');
if (point1 && point2) {
var touching = isTouchingHex(point1[0], point1[1], point2[0], point2[1]) ? 'true' : 'false';
$isTouching.html(touching)
} else {
$isTouching.html('');
}
}
function isTouchingHex(x1, y1, x2, y2) {
var deltaX = x1 - x2;
var deltaY = y1 - y2;
$dx.html(deltaX);
$dy.html(deltaY);
// check same x
if (deltaX === 0) {
switch (deltaY) {
// check bottom left
case -1:
// check bottom
case -2:
// check top right
case 1:
// check above
case 2:
return true;
break;
}
} else if (deltaX === 1) {
switch (deltaY) {
// check bottom left
case -1:
// check top left
case 1:
return true;
break;
}
}else if (deltaX === -1) {
switch (deltaY) {
// check bottom right
case -1:
return true;
break;
}
}
return false;
}

Random "spawn" of divs

I'm trying to create a "spawn point" for a div. I have made it work and I have a working collision detector for it. There are two things I wanted to ask regarding my code.
How do I get my code to work with more than one player (window.i). - At the moment, after an hour of fiddling, I've only broken my code. This whole area screws up the collision detector, I have more than one player showing at times, but I'm unable to move.
How do I make it so that it detects the contact before it happens - I've tried working with the "tank's" margin and subtracting it's width, so that before it makes contact it calls an event, but it has been unsuccessful and completely stopped the collision function working.
I'm sorry that it's asking a lot, I really do understand that, but the issues come into eachother and rebound off so I thought it was best I put it all into one question rather than 2 separate ones an hour apart.
function animate() {
var tank = document.createElement("div");
tank.id= "tank";
tank.style.marginLeft="0px";
tank.style.marginTop="0px";
tank.style.height="10px";
tank.style.width="10px";
document.body.appendChild(tank);
x = parseInt(tank.style.marginLeft);
y = parseInt(tank.style.marginTop);
document.onkeydown = function () {
e = window.event;
if (e.keyCode == '37') {
if (x > 0) {
if (collisionDetector() == false) {
x = x - 10;
tank.style.marginLeft = x + "px";
} else {
alert();
}
}
} else if (e.keyCode == '39') {
if (x < 790) {
if (collisionDetector() == false) {
x = x + 10;
tank.style.marginLeft = x + "px";
} else {
alert();
}
}
} else if (e.keyCode == '38') {
if (y > 0) {
if (collisionDetector() == false) {
y = y - 10;
tank.style.marginTop = y + "px";
} else {
alert();
}
}
} else if (e.keyCode == '40') {
if (y < 490) {
if (collisionDetector() == false) {
y = y + 10;
tank.style.marginTop = y + "px";
} else {
alert();
}
}
}
}
}
window.lives = 3;
function playerSpawn() {
window.i = 1;
while (i > 0) {
var player = document.createElement("div");
randMarL = Math.ceil(Math.random()*80)*10;
randMarT = Math.ceil(Math.random()*50)*10;
player.id = "player";
player.style.marginLeft= randMarL + "px";
player.style.marginTop= randMarT + "px";
player.style.height="10px";
player.style.width="10px";
document.body.appendChild(player);
i--;
}
}
function collisionDetector() {
x1 = tank.style.marginLeft;
x2 = player.style.marginLeft;
y1 = tank.style.marginTop;
y2 = player.style.marginTop;
if ((x1 == x2 && y1 == y2)) {
return true;
} else {
return false;
}
}

Moving right immediately pushes div far off screen region

When I attempt to move the div (tank) to the right ONLY in the first "movement command", and only in that direction, I come across in issue whereby my div shoots off a few thousand pixels to the right, way off of the screen region. Was hoping someone would assist me to see why this is.
function animate() {
var tank = document.getElementById("tank");
tank.style.marginLeft="360px";
tank.style.marginTop="440px";
window.xpos = tank.style.marginLeft;
window.ypos = tank.style.marginTop;
window.x = xpos.replace("px","");
window.y = ypos.replace("px","");
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '37') {
if (x > 0) {
x = x - 20;
tank.style.marginLeft = x + "px";
}
} else if (e.keyCode == '39') {
if (x < 70) {
x = x + 20;
tank.style.marginLeft = x + "px";
}
} else if (e.keyCode == '38') {
if (y > 0) {
y = y - 20;
tank.style.marginTop = y + "px";
}
} else if (e.keyCode == '40') {
if (y < 440) {
y = y + 20;
tank.style.marginTop = y + "px";
}
}
}
checkKey(e);
}
window.lives = 3;
function destroy() {
if (lives != 0) {
alert("Life Lost!");
lives--;
window.collision == false;
animate();
} else {
alert("Try Again!");
}
}
window.collision = true;
function state() {
if (collision == false) {
window.state = 1;
} else if (collision == true) {
window.state = 0;
}
return state;
}
state();
if (state == 1) {
animate();
} else {
destroy();
}
You think you are doing a math operation but what you really are doing a string concatenation. In Javascript "360"-20 equals 340 because in this case the string is converted to a number and then an arithmetic subtraction is performed with both numeric values, however a different set of rules apply for the plus operator: in this case "360"+20 yields "36020" because the number is converted to a string and then both strings are concatenated.
Do this:
window.x = Number(xpos.replace("px",""));
window.y = Number(ypos.replace("px",""));

Checking element visibility using elementFromPoint() method

I'm trying to check to make sure an item is visible before I start working on it using the following function
isVisible: function (node, doc, x, y) {
var el = doc.elementFromPoint(x, y);
if (node === el) return true;
else return false;
},
x and y are positions of the selected node and is calculated by
findPos: function (node) {
var pos = new Object();
pos.left = pos.top = 0;
if (node.offsetParent) {
do {
pos.left += node.offsetLeft;
pos.top += node.offsetTop;
} while (node = node.offsetParent);
}
return pos;
}
Everything works fine. However, when I scroll the page down, the isVisible function is no longer returning the right value. This is caused by the position having changed but the find position function not returning the right value.
Is there a method to get the position of an element like the reverse of elementFromPoint? Or does anyone have another method?
I just wrote an isVisible() method that uses the elementFromPoint() method and should work in IE9+ to detect if an element is visible.
var isVisible = function(elem) {
var w = window, d = document, height, rects, on_top;
if(!elem || (elem && elem.nodeType !== 1) || !elem.getClientRects || !d.elementFromPoint || !d.querySelector || !elem.contains) {
return false;
}
if (elem.offsetWidth === 0 || elem.offsetHeight === 0) {
return false;
}
height = w.innerHeight ? w.innerHeight: d.documentElement.clientHeight;
rects = elem.getClientRects();
on_top = function(r, elem) {
var x = (r.left + r.right)/2,
y = (r.top + r.bottom)/2,
elemFromPoint = d.elementFromPoint(x, y);
return (elemFromPoint === elem || elem.contains(elemFromPoint));
};
for (var i = 0, l = rects.length; i < l; i++) {
var r = rects[i],
in_viewport = r.top > 0 ? r.top <= height : (r.bottom > 0 && r.bottom <= height);
if (in_viewport && on_top(r, elem)) {
return true;
}
}
return false;
};
You would call it like this: isVisible(document.getElementById('at-follow'));
Also, here is the gist of it.
I was able to fix this by adding window.scrollX and window.scrollY to the doc.elementFromPoint() input parameters x and y
isVisible: function (node, doc, x, y)
{
var el = doc.elementFromPoint(x-window.scrollX, y-window.scrollY);
if (node === el) return true;
else return false;
},
this seems to work fine
This library should be what you're looking for: https://github.com/cpatik/within-viewport/blob/master/withinViewport.js

Categories