Looking for some direction and help. I am new to JavaScript and NodeJS and have not been able to find anything online on how to do this. I've written a minesweeper game in JavaScript and would like to be able to inject user written code into the game loop instead of taking inputs.
The main problem I am running into is getting access to the methods I've built into the game class. Here's the code.
class Game {
constructor() {
this.GameBoard = new MineSweeperBoard(true);
autoBind(this);
}
pop(x ,y){
this.GameBoard.pop(x, y);
}
flag(x, y){
this.GameBoard.flag(x,y);
}
removeFlag(x,y){
this.GameBoard.RemoveFlag(x,y);
}
checkWin(){
this.GameBoard.CheckForWin();
}
getGameBoard(){
return this.GameBoard.GetRevealedGameBoard()
}
}
function StartGame() {
let CurrentGame = new Game();
let win = false;
while(CurrentGame.GameBoard.RunGame) {
//User Code here
*User written code should run right about here.*
// Check win condition
if(CurrentGame.checkWin()){
win = true;
}
}
Any help or direction would be appreciated.
*** Edit ***
To answer some question that have been asked.
1: This isn't secure: Yes I understand there are potential security implications to running user generated code. As of right now that is not a concern as this is mostly a proof of concept.
2: Why do I want to do this: Because I want to see if it's possible and I know others have found ways to securely run user code (i.e. Screeps). Right now I would like to see what is possible.
Related
I have been bashing my head on this and I know that it's probably an easy fix but I can't for the life of me figure out what is wrong. I am trying to call a class function within a for loop and I've tried a few methods but i've come up with diddly-squat so far. I'll plug in the relevant snippets below. For reference this is a project to make a web-based simple game and I've chosen a bastardization of galaga and asteroids hence, "ship" and "asteroids." My question is why won't it populate the class function .spawn(); that's been assigned to the items in the "rock" iterative? Any advice would be extremely helpful.
var rock = []; //I know global variables = evil, but I'm still early in development
function setup() {
...
//Asteroids
for(var i = 0; i<5; i++){
var y = random(0,350);
var speed = random(2,5);
rock.push(new asteroid(800,y,speed,10));
}
...
}
function draw() {
...
//Spawn Asteroids
//rock[0].spawn(); //<-------Single instance of object from array(works as intended)
/*for (let c of rock){ //<-------Tried changing variable type to const as well because I was pulling my hair out and that did nothing either.
this.spawn();
}*/
/*for (let c in rock){ //<-------Covering my bases
this.spawn();
}*/
rock.forEach(index => this.spawn()); //<------Last thing I tried
...
}
//////////////////////////////////////////////////////////////////////////////
class asteroid {
...
spawn(){
this.move();
this.display();
this.offScreen();
this.speed = random(2,5);
}
...
}
////////////////////////////////////////////////////////////////////////////////////////////
Note: I tried to create a facsimile of another for loop that I used for
the ship attack but it didn't work either. It's this snippet below.
draw(){
this.bullets.forEach((bullet) => {
if(this.isBulletOffScreen(bullet)){
const index = this.bullets.indexOf(bullet);
this.bullets.splice(index, 1);
}
bullet.draw();
});
}
I don't have the one I tried to adapt because I felt I was way over complicating a simple object so I erased it but this is the working code for the projectile controller class that I was copying from.
P.S. Here is the Error message I keep getting.
*🌸 p5.js says: [sketch.js, line 86] "spawn" could not be called as a function. Verify whether "this" has "spawn" in it and check the
spelling, letter-casing (JavaScript is case-sensitive) and its type.
More info: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Errors/Not_a_function#What_went_wrong
sketch.js:86*
** Uncaught TypeError: this.spawn is not a function
at draw (sketch.js:86:10)
at p5._main.default.redraw (p5.js:71990:27)
at _draw (p5.js:64140:25) ​**
#Teemu had the answer and it took a bit for my thick skull to work it out. By adjusting the forEach to resemble this:
rock.forEach(index => index.spawn());
They spawn and now I can start moving forward again. Thank you again Teemu!
I am programming a multi-player game with JavaScript and html. For this objective I need communication between the players. How can I manage this?
My code:
enchant();
window.onload = function() {
var game = new Game(320, 320);
Here my first question: It should be counted how many player is that now, who entered the room last. Then a number should be assigned to this player. I´d like to solve this with a function.
var my_bear = get_player_number();
game.preload('chara1.gif');
game.fps=15;
var bears = [];
game.onload = function() {
var ix;
var bear;
for (ix = 0; ix < 5; ix++) {
bear=new Sprite(32, 32);
bear.image = game.assets['chara1.gif'];
bear.frame = 4;
bear.x=Math.random()*300;
bear.y=Math.random()*300;
game.rootScene.addChild(bear);
bears.push(bear);
}
};
game.start();
var addit=6;
document.addEventListener('keyup',function (evt) {
if(evt.keyCode == 38){bears[my_bear-1].y-=addit;}
if(evt.keyCode == 39){bears[my_bear-1].x+=addit;}
if(evt.keyCode == 40){bears[my_bear-1].y+=addit;}
if(evt.keyCode == 37){bears[my_bear-1].x-=addit;}
});
}
Due to this simplification of my programme you have 5 bears. One of them you can control with the arrow-keys (the bear with the value of the variable “my_bear”).
But it´s still a single-player game yet...
init_other_players(my_bear);
A function would be perfect, which detects and indicates any movement of a player on an other computer.
Webspace an two domains are available for my programme.
I´m very looking forward to your helpful answer, thank you !!!
First, if you want multiplayer, you need something to manage the rooms and such, so you need a server. For games, I'd suggest NodeJS. Node is a server app built in JS, so a language you are familiar with. You don't need to know too much about node for now, simply running it will be enough while you progress on your code, after that I'd say you should look a bit more into it.
After, I'd look into Socket.io which lets you manage your websockets and therefore communication between the users and the server. There are tutorials about a chat in the Get Started section of the website which will you let you know the basics of communication between users.
From there you can create the logic for your rooms and the rest of your game! It may look like a lot to learn but, honstly, it's well explained and quite easy to get a grasp of.
I stuck in a problem by coding on a javascript webapp with firebase:
function start() {
setInterval(getComps, 2000);
}
function getComps() {
permis=true;
for (var pc=policeNum; pc>0; pc--) {
policeRef.child(pc).once('value', function(snapshot) {
var oldData = snapshot.val();
//KI:
var compX=newX-oldData.X;
var compY=newY-oldData.Y;
updatePosition(compX, compY);
});
}
}
(The real code of the app is of course more complicated but this is enough to understand the problem I think) (The start() is called with a button in my index.html)
When I run my app I can see that updatePosition() is only called once in the beginning but not later again in my wanted interval. Do someone know what´s wrong here and can give me a example or explanation of a better code.
Thank you for every answer, I hope you can understand what I mean. (all variables are of course defined)
Not sure if I'm going about this the right way. I'll map out what I'm trying to achieve and please give me any feedback you can. Also very new to meteor so sorry if I'm a bit uneducated in some aspects. This is going to be a two player game where users login in with accounts-twitter or accounts-facebook. Here's the tricky part it will only initialize the game if there are two users logged in. To figure out who is logged in I have put this line of code in my server portion:
if (Meteor.isServer) {
Meteor.publish("userStatus", function() {
return Meteor.users.find({
"status.online": true
})
});
}
My idea of what needs to be done is write an if statement if(userStatus === true){get a users "_id"} then push that user into an array and have a for loop run through every 2 users signed on in the array and initialize a game for them. Also the main question is how do I grab the users ID if status.online is true? Also any input on how to make this more efficient is much appreciated.
Answering your "main question," you would do this with a mongoDB for-each like so.
Meteor.methods({
getOnline : function(){
var retArr = new Array();
Meteor.users.find({"status.online": true}).forEach(function(u){
retArr.push(u._id); //populated retArr with the id of users online
});
return retArr;
}
});
If I left out something or you need clarification on something, please comment.
I always admired the stackoverflow.com website.
I also, was always curious about what the Javascript:OpenID.Signin('example') here, in the login page of the Stackoverflow.com, does.
You see, i would like to implement something similar to my website, and this one is the question that first came in my mind. (I mean provide, separate button for every different connect provider).
Please keep in mind that i am a newbie and i would prefer, if possible, simple answers.
Thank you in advance.
PS. If you are not willing to tell me what the Javascript:OpenID.Signin('example') does, could you please tell me how can i achieve the same functionality?
I am totally lost with the OpenId stuff and in any case would not like to mention the OpenID as is, in my website. I am sure it will complicate things for the users of my website too. I would prefer a solution, connect with Google, Facebook etc separate buttons.
If you view source on the page your talking about you can see a script tag for an outside file
<script type="text/javascript" src="http://sstatic.net/Js/third-party/openid-jquery.js?v=8"></script>
If you look there, you'll see it contains a global var called openid which contains a function called signin among other things.
Here's the function body if you're curious
signin: function (box_id, onload) {
var provider = providers[box_id];
if (!provider) { return; }
this.highlight(box_id);
if (box_id == 'openid') {
$('#openid_input_area').empty();
this.setOpenIdUrl("");
$("#openid_identifier").focus();
return;
}
// prompt user for input?
if (provider['label']) {
this.useInputBox(provider);
this.provider_url = provider['url'];
} else {
$('.' + box_id).css('cursor', 'wait');
if (provider['oauth_version']) {
this.setOAuthInfo(provider['oauth_version'], provider['oauth_server']);
} else {
this.setOpenIdUrl(provider['url']);
}
this.provider_url = null;
if (!onload) {
$('#openid_form').submit();
}
}
}