So I'm making a shop kind of place and I'm trying to let the player purchase the first item in the shop's object array by pressing the number 0 but the key pressed isn't letting me access into the if statement. I'm able to tell it is because of the key because when I removed that restriction I was allowed access into the if statement.
else if (inShop === true && key === "1") {
if (player.coins > 50) {
var buying = true
}
for (var i = 0; i < shop.length; i++) {
console.log(shop[i].name, shop[i].price + " press " + i + " to purchase")
}
}
if (buying === true && player.coins > shop[0].price && key=== "0") {
console.log("yo")
player.coins = player.coins - shop[0].price
console.log(player.coins)
sceneNumber = sceneNumber + 1
}
If this is all in the keyPressed block, I think I know what your problem is.
When you press any key, whatever key is pressed is saved as the key variable. Then the computer runs the code that's in the keyPressed block. It does not listen for user input in the middle of that block, but waits until the end. Sort of like this (I might have some details wrong):
run setup block
listen for user input: no input heard
run draw block
listen for user input: no input heard
REPEAT the above 2 things over and over
run draw block
listen for user input: the "1" key was pressed
key = '1'; keyCode = 49;
run keyPressed block
run draw block
etc.
That pretty much means that you can't do multiple layers of input in the keyPressed block. Since buying === true only if key === '1', the statement buying === true && key === "0" is always false.
Often, the keyPressed block will look something like this:
function keyPressed() {
if (key === "1") {
...
} else if (key === "2") {
...
} ...
}
One solution is to turn buying into a global variable:
let buying = false;
function setup() {
...
}
function draw() {
...
}
function keyPressed() {
if (key === "1") {
if (inShop) {
if (player.coins > 50) {
buying = true;
}
for (var i = 0; i < shop.length; i++) {
console.log(shop[i].name, shop[i].price + " press " + i + " to purchase");
}
}
} else if (key === "0") {
if (buying && player.coins > shop[0].price) {
console.log("yo");
player.coins = player.coins - shop[0].price;
console.log(player.coins);
sceneNumber = sceneNumber + 1;
buying = false; //I don't know if you'd want this to happen.
}
}
}
Related
I am having trouble getting my pausing to work well.
When I hit the 'p' key, I want to toggle pause on/off.
I have created this fiddle
window.keyController = {
p: false, // p
}
Is the keycontroller i set to capture multiple keys, i only have the P key here now.
I use two event listeners to set this.
// listeners
window.addEventListener("keydown", (e) => {
e.preventDefault();
if (e.key == "p") {
keyController.p = true;
}
});
window.addEventListener("keyup", (e) => {
if (e.key == "p") {
keyController.p = false;
}
});
Then in my main loop, a request anim frame loop.
i am checking if p is hit or true and then looping trough game loop.
if (keyController.p == true) { // 'p' pause on/off toggle
pause = !pause;
}
if (pause == 0 || (pause == 1 && cyc != 14)) { // pause=0 Or (pause=1 And cyc<>(16-mov/2))
if (cyc == 0) {
levticker -= 1;
if (levticker == 0) {
levticker = 15;
levtime -= 1;
}
if (levtime < 0) levtime = 0;
}
cyc = cyc + 2;
if (cyc == 16) cyc = 0;
}
Any ideas what i am doing wrong, should we be able to pause between each middle figure and not skip or delay? this middle timer counts down from 15 to 0 so 16 cycles before we effect the first timer.
I'm trying to use the Event delegation/switch statement for the first time in my life, and I'm having trouble with for loop. When it was 'array[i]' it wasn't a problem. But now I'm removing the for loop to use the event delegation and putting it inside of a function, it keeps giving me errors, and I don't know what parameter can replace (and make the code work again) that array[i] in the new function. Any help or explanation will be appreciated.
//original code
const numbers = document.querySelectorAll(".number");
for (let i = 0; i < numbers.length; i++) {
numbers[i].addEventListener("click", function () {
if (display.value.length < 13) {
return;
}
if (display.value == "0" && numbers[i] != dot) {
display.value = numbers[i].innerText;
calculation = display.value;
} else {
if (numbers[i] == dot && display.value.includes(".")) {
return;
} else if (numbers[i] == dot && display.value == "") {
return;
} else {
display.value += numbers[i].innerText;
calculation = display.value;
}
}
buttonEffect(numbers[i], "number-active");
});
}
// New code
const numbers = document.querySelectorAll(".number");
function numberClick(number) {
if (display.value.length > 13) {
return;
}
if (display.value == "0" && this != dot) {
display.value = number.innerText;
calculation = display.value;
} else {
if (numbers == dot && display.value.includes(".")) {
return;
} else if (number == dot && display.value == "") {
return;
} else {
display.value += number.innerText;
calculation = display.value;
}
}
operatorOnOff = false;
buttonEffect(number, "number-active");
}
document.querySelector(".wrapper").addEventListener("click", (e) => {
switch (e.target.dataset.key) {
case "number":
numberClick();
break;
}
});
You pass the element that was the target of the click into numberClick and use it where previously you used numbers[i]. It looks like you're already doing the second part of that, and you even have a parameter declared for it, you just need to pass the element in:
numberClick(e.target);
Note that if your .number elements have child elements, target may be one of those child elements rather than .number. To handle that, you can use the DOM's relatively-new closest method, probably combined with contains to make sure it didn't match something surrounding .wrapper:
document.querySelector(".wrapper").addEventListener("click", (e) => {
const number = e.target.closest(".number");
if (number && this.contains(number) && number.dataset.key) {
numberClick(number);
}
});
There are polyfills you can use if you need to support obsolete browsers, or just do the loop yourself:
document.querySelector(".wrapper").addEventListener("click", (e) => {
let number = e.target;
while (number && !number.matches(".number")) {
if (this === number) {
return; // Reached the wrapper without finding it
}
number = number.parentElement;
}
if (number && number.dataset.key) {
numberClick(number);
}
});
I am working on a typing game and I am trying to imitate the same effect of highlighting of the characters to be typed like in https://www.ratatype.com/typing-test/test/. However, it was harder than what I imagined.
I created code which uses replace function to give style on the character. However, it only replaces the first instance of the character and the other instances, it won't do what it was supposed to do.
const originTextDiv = document.getElementById('origin-text'); //the div that was supposed to be highlighted.
function spellCheck() {
let textEntered = textArea.value;
//let textCharEntered = textEntered.split("");
let originTextMatch = originText.substring(0, textEntered.length);
// console.log(textEntered);
var key = event.keyCode || event.charCode;
originChar = originText.split("");
//console.log(originTextDiv);
char = originTextDiv.textContent;
//console.log(char);
console.log(originChar[index]);
//console.log(textCharEntered);
if (textEntered == originText) {
textWrapper.style.borderColor = 'orange';
$("#myModal").modal();
stop();
} else {
if (textEntered == originTextMatch) {
textWrapper.style.borderColor = 'green';
textArea.style.backgroundColor = 'white';
// if (!(key == 20 || key == 16 || key == 18 || key == 8 || key == 46 || key ==17 )){
originTextDiv.innerHTML = char.replace(originChar[index], '<span style="background-color:green;">' +originChar[index]+ '</span>'); //here is the code where it is highlighting
++index;
// }
// if (key == 8 || key == 46){
// --index;
// }
} else {
textWrapper.style.borderColor = 'red';
textArea.style.backgroundColor='f23a49';
originTextDiv.innerHTML = char.replace(originChar[index], '<span style="background-color:red;">' +originChar[index]+ '</span>');
if (!(key == 8 || key == 46)){
error++;
}
}
}
}
I expected to have it work as intended but I didn't knew replace only replaces the first instance. I tried to look at on replaceAt functions for javascript but when I tried it the replaceAt also replaces the span tag attached. Could someone give me some pointers on how to recreate the same effect as the reference above?
Hello i'm trying to add events and location to an function so whenever a block is placed on an certain block it gives you a message and adds +1 to the score it doesn't have any errors but it doesn't work I have never programmed in javascript before so.
var score = 0
events.blockPlace( function (event, location) {
if (location.x == -239.538 && location.y == 71.000 &&
location.z ==314.407 ) {
echo(event.player, 'You have just placed an block');
var scored = score =+ 1
}
});
Code piece below should work with Spigot and Scriptcraft.
The block position is stored in event.block. The location variable you provided is a method to cancel this event.
The positions provided by the block are integers not floats.
var score = 0;
var block_place_event = events.blockPlace(function(event){
if ((event.block.x == -239) && (event.block.y == 71) && (event.block.z == 314)){
echo(event.player, 'You have just place an block');
score = score + 1;
}
});
You can get the location for any block event from the block itself
var score = 0
events.blockPlace( function (event) {
var location = event.block.location
if (location.x == -239 && location.y == 71 &&
location.z == 314 ) {
echo(event.player, 'You have just placed a block');
var scored = score =+ 1
}
});
You also will want to cut off any decimal points, since blocks have whole number locations.
I have encountered a strange behavior on android browser / webview. I was testing an input that will automatically format to phone number format "(xxx) xxx-xxxx". But then what happened was when I tapped or press any number on androids keyboard, the first input was like this "(x" but then the cursor was in between "(" and "x". Is there a way to put the cursor after "x" value?
I tested this on iPhone and windows web browsers and it works fine. Please let me know if there are mistakes on my jquery or javascripts.
Thanks
HTML CODE:
<html>
<head>
<title>Sample Phone Number Format</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
</head>
<body>
<input type="text" id="phone" />
<script type="text/javascript">
$('#phone').on('keydown', function (event) {
objval = $(this).val();
if (event.keyCode == 46 || event.keyCode == 8) {} else {
if (!((event.keyCode > 47 && event.keyCode < 58) || (event.keyCode > 95 && event.keyCode < 106) || (objval.length > 13))) {
event.preventDefault();
} else {
if (objval.length == 0) {
$(this).val(objval + '(');
alert(objval + '(');
} else if (objval.length == 4) {
$(this).val(objval + ') ');
alert(objval + ') ');
} else if (objval.length == 9) {
$(this).val(objval + '-');
alert(objval + '-');
} else if (objval.length >= 14) {
if (event.keyCode == 9) {
return;
} else {
event.preventDefault();
}
}
}
}
});
$('#phone').on('keydown', function (event) {
var objVal = $(this).val();
if(objVal.length < 14)
{
validateCallerForm(objVal + String.fromCharCode((96 <= event.keyCode && event.keyCode <= 105)? event.keyCode-48 : event.keyCode));
}
});
//Validates proper phone format, true if valid phone number, false otherwise
function isValidPhoneNumber(elementValue) {
var numberPattern = /^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/;
return numberPattern.test(elementValue);
}
//validates entire caller form, also updates css classes for proper response
function validateCallerForm(PhoneNumber) {
if (isValidPhoneNumber(PhoneNumber)) {
alert("true");
} else {
alert("false");
}
}
</script>
</body>
</html>
Giving +50 Bounty to who'm will answer this correctly
you have to first define listener for typing and copy-paste like below (not required) :
$("#phone").keyup( function() {
maskLine(this);
});
$("#phone").change( function() {
maskLine(this);
});
Then, to manage cursor placement, you have to cache previous phone number and then, you could compare difference and update cursor position if needed.
So declare, you have to declare a global array like this :
var _cacheElementValues = new Array();
At last, you can check the function below, it applies your mask to phone number field and manage cursor placement :
function maskLine( element ) {
element = $(element);
var maskedLine = '';
var line = element.attr('value');
// check the cache of the input and abord if no change since last treatment
if (_cacheElementValues[element.attr('id')] != undefined && _cacheElementValues[element.attr('id')] == line) {
return;
}
line = line.replace(/\D/g, ''); // remove all characters != digits
line = line.substring(0, 10);
if (line != '') {
// apply mask
if (line.length <= 2 ) {
maskedLine = "(" + line;
} else if (line.length < 6) {
maskedLine = line.replace(/^([0-9]{3})([0-9]{0,3})/g, '($1) $2');
} else {
// mask : '(XXX) XXX-XXXX'
maskedLine = line.replace(/^([0-9]{3})([0-9]{3})([0-9]{0,4})/g, '($1) $2-$3');
}
}
// define cursor position at the end of the input by default
var pos = maskedLine.length;
// Change cursor placement if necessary
if (typeof element[0].selectionStart != 'undefined') {
var start = element[0].selectionStart;
var end = element[0].selectionEnd;
var insText = element[0].value.substring(start, end);
// get current cursor placement
if (insText.length == 0) {
pos = start;
} else {
pos = start + insText.length;
}
// find how many digits typing since last mask application
var previousLength = 0;
if (_cacheElementValues[element.attr('id')] != undefined) {
previousLength = _cacheElementValues[element.attr('id')].replace(/\s/g, '').length;
}
var diff = maskedLine.replace(/\s/g, '').length - previousLength;
// if sum of new typing digit is > 0 : we change cursor placement
if (diff > 0) {
pos += (diff - 1) + Math.round((diff-1)/3);
if (pos%6 == 0 && maskedLine.length >= pos+1) pos++;
}
}
// update input data & cache
element.val(maskedLine);
_cacheElementValues[element.attr('id')] = maskedLine;
// update cursor placement
element[0].selectionStart = element[0].selectionEnd = pos;
}
You can find this example on jsFiddle : http://jsfiddle.net/UE9LB/5/
I hope this little explantion can solve your problem ;)
Enjoy !
ps: i apologize for my poor english :s
I'd recommend at least starting with an existing plugin rather than going through your own isolated rounds of solving issues.
http://digitalbush.com/projects/masked-input-plugin/
https://github.com/igorescobar/jQuery-Mask-Plugin
The short answer is to set the selectionStart and selectionEnd properties of the input element. After you format the value, set these properties to this.value.length.
this.selectionStart = this.value.length;
this.selectionEnd = this.value.length;
But, where you are going to run into trouble is when the cursor is not at the end of the text. Eg, the user has manually positioned the cursor to a position within the text. To prevent the cursor from jumping to the end, you will need to detect the cursor position before you format the input, then put the cursor back in the appropriate position after formatting.
Edit: This jsFiddle may get you started, but isn't perfect yet.
I rewrite the code on my #phone keydown event and this will work on iPhone, Android, webkit browsers.
$('#phone').on('keydown', function (event) {
if (event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39) {
// ignore if BKSPCE, left arrow, or right arrow
} else {
// validate if anything else
inputval = $(this).val();
var string = inputval.replace(/[^0-9]/g, "");
var first3 = string.substring(0,3);
var next3 = string.substring(3,6);
var next4 = string.substring(6,10);
var string = ("(" + first3 + ") " + next3 + "-" + next4);
$(this).val(string);
}
});