Frogger JavaScript game - Redefine Object Property - javascript

I am trying to write a frogger game like in OOP javascript. I have a couple of sprites for the player to choose from. What I want to achieve is that when the user selects the specific sprite, it updates the correct one when instantiating the player object.
I get an error when I try to redefine the property. I have tried a couple of solutions but with no success. What am i doing wrong? please help!
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>First Attempt: Frogger</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/dd.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-4 offset-sm-2 characters" style="border:1px solid black">
<img src="images/char-boy.png" alt="char-boy"><input type="radio" name="sprite" value="images/char-boy.png" checked="checked">
<img src="images/char-cat-girl.png" alt="char-boy"><input type="radio" name="sprite" value="images/char-cat-girl.png">
<img src="images/char-horn-girl.png" alt="char-boy"><input type="radio" name="sprite" value="images/char-horn-girl.png">
<img src="images/char-pink-girl.png" alt="char-boy"><input type="radio" name="sprite" value="images/char-pink-girl.png">
<img src="images/char-princess-girl.png" alt="char-boy"><input type="radio" name="sprite" value="images/char-princess-girl.png">
</div>
<div class="col-sm-6" id="game"></div>
</div>
</div>
<script src="js/resources.js"></script>
<script src="js/app.js"></script>
<script src="js/engine.js"></script>
</body>
</html>
JavaScript:
var Player = function(){
//What sprite to use
this.sprite = $("input[name='sprite']:checked").val();
//initial x location
this.x = 200;
//initial y location
this.y = 400;
};
$(document).on("click", 'input:radio[name="sprite"]',
function(){
var result = $("input[name='sprite']:checked").val();
console.log(result);
Object.defineProperty(Player.prototype, 'sprite', {
get: function(){
return this.sprite;
},
set: function(result){
this.sprite = result;
}
});
}
);

You could wrap the Player constructor in a closure to pass in the sprite before instantiation:
var PlayerWithSprite = function (sprite) {
return function () {
//What sprite to use
this.sprite = sprite;
//initial x location
this.x = 200;
//initial y location
this.y = 400;
};
};
var Player = PlayerWithSprite('my-sprite');
var playerInstance = new Player();
console.log(playerInstance);

Here is a Player class to get you started:
class Player
{
constructor(x,y)
{
var player = this;
this.x = x;
this.y = y;
this.sprite = null;
$('input:radio[name="sprite"]').click(function(){
player.sprite = $("input[name='sprite']:checked").val();
});
}
}
$(function(){
new Player(200,400);
});

You are getting an error because by default you can't redefine properties in JavaScript. See this answer for more information. If you want to define properties on an object, it should be one in the player constructor function.

Related

closePath() Moving Polygon

The following code below is what is needed to make a simple triangle. I want to keep the triangle in that exact position and add this to my canvas.
can = document.getElementById("gameCanvas");
var ctx = can.getContext("2d");
ctx.beginPath();
ctx.moveTo(1, 20);
ctx.lineTo(20, 100);
ctx.lineTo(70, 100);
ctx.closePath();
ctx.stroke();
If you run the code below, the triangle is there for a split second and then disappears. I need it to stay there along with the three equations. I created the function path(); in effort to keep the triangle positioned in the upper left corner. I am not sure how to keep the triangle there and do all of this.
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="//code.createjs.com/createjs-2013.09.25.combined.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
#gameCanvas {
background-color: lightyellow;
}
</style>
<div class="canvasHolder1">
<div id="eqn1"> 3+3=<input type="text" id="q1" />
</div>
<div id="eqn2"> 3+2=<input type="text" id="q2" />
</div>
<div id="eqn3"> 5+2=<input type="text" id="q3" />
</div>
<canvas id="gameCanvas" width="600" height="600">Not supported</canvas>
<script type="text/javascript">
var m=1;
var stage = new createjs.Stage("gameCanvas");
var obj=[];
can = document.getElementById("gameCanvas");
var ctx = can.getContext("2d");
ctx.beginPath();
ctx.moveTo(1, 20);
ctx.lineTo(20, 100);
ctx.lineTo(70, 100);
ctx.closePath();
ctx.stroke();
function startGame() {
obj[1] = new createjs.DOMElement(document.getElementById(`eqn${1}`));
obj[2] = new createjs.DOMElement(document.getElementById(`eqn${2}`));
stage.addChild(obj[1]);
stage.addChild(obj[2]);
createjs.Ticker.addEventListener("tick", handleTick);
createjs.Ticker.setFPS(60);
function handleTick(event){
drop(1);
drop(2);
path();
stage.update();
}
}
function drop(i){
obj[1].x =40;
obj[1].y =50;
obj[2].x =300;
obj[2].y =50;
}
function path(){
ctx.x=1;
ctx.y=1;
}
</script>
<body onload="startGame();">
<div >
<canvas>This browser or document mode doesn't support canvas object.</canvas>
</div>
</body>
</html>
Take a look at this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Math Game</title>
<script src="//code.createjs.com/createjs-2013.09.25.combined.js"></script>
</head>
<body onload="startGame();">
<div class="canvasHolder1">
<div id="eqn1"> 3+3=<input type="text" id="q1" /></div>
<div id="eqn2"> 3+2=<input type="text" id="q2" /></div>
<div id="eqn3"> 5+2=<input type="text" id="q3" /></div>
<canvas id="gameCanvas" width="600" height="200">Not supported</canvas>
</div>
<script>
var stage = new createjs.Stage("gameCanvas");
var can = document.getElementById("gameCanvas");
var ctx = can.getContext("2d");
var obj = [];
function drawTriangle() {
ctx.beginPath();
ctx.moveTo(1, 20);
ctx.lineTo(20, 100);
ctx.lineTo(70, 100);
ctx.closePath();
ctx.stroke();
}
function startGame() {
obj[1] = new createjs.DOMElement(document.getElementById("eqn1"));
obj[1].x = 40;
obj[1].y = 50;
stage.addChild(obj[1]);
obj[2] = new createjs.DOMElement(document.getElementById("eqn2"));
obj[2].x = 300;
obj[2].y = 50;
stage.addChild(obj[2]);
stage.update();
drawTriangle();
}
</script>
</body>
</html>
You can see I created a new function drawTriangle it will be called at the end of your startGame that way the triangle is the last item drawn in the canvas.
I'm not sure why you needed the Ticker so I remove it, same with the other functions, they did not make much sense to me, no need for what you are trying to accomplish at the moment.
Now to your problem... in my implementation I have the drawTriangle as the last action in the startGame, but if we change the order, to something like this:
drawTriangle();
stage.update();
The triangle disappears!
My educated guess is that stage.update() clears the entire canvas and draws what it "knows" the triangle drawing is happening outside the stage so we need to always draw it after.
Looking at the code documentation for update:
https://www.createjs.com/docs/easeljs/files/easeljs_display_Stage.js.html#l349
there is an if statement if (this.autoClear) { that does exactly what we are seeing in your sample, and the default value of autoClear is true:
https://www.createjs.com/docs/easeljs/classes/Stage.html#property_autoClear
Also worth pointing out... there is a native createjs way to draw lines:
https://createjs.com/docs/easeljs/classes/Graphics.html#method_moveTo
https://createjs.com/docs/easeljs/classes/Graphics.html#method_lineTo
There is nothing wrong with your approach, you are using both createjs and directly drawing in the canvas via getContext("2d") you just have to plan accordingly, but my recommendation, if there is a native approach I would stick with that, here is a sample code:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Math Game</title>
<script src="//code.createjs.com/createjs-2013.09.25.combined.js"></script>
</head>
<body onload="startGame();">
<div class="canvasHolder1">
<div id="eqn1"> 3+3=<input type="text" id="q1" /></div>
<canvas id="gameCanvas" width="600" height="160">Not supported</canvas>
</div>
<script>
function startGame() {
var stage = new createjs.Stage("gameCanvas");
var eqn1 = new createjs.DOMElement(document.getElementById("eqn1"));
eqn1.x = eqn1.y = 50;
stage.addChild(eqn1);
var triangle = new createjs.Shape();
triangle.graphics.beginStroke("black")
triangle.graphics.moveTo(1, 20);
triangle.graphics.lineTo(20, 100);
triangle.graphics.lineTo(70, 100);
triangle.graphics.lineTo(1, 20);
stage.addChild(triangle);
stage.update();
}
</script>
</body>
</html>

Shrink img using javascript

I'm trying to shrink an image based off of what I learned on the mobile app SoloLearn. Please help.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="xyz.css"/>
</head>
<body>
<img id="image" src="myImage.jpg"/>
<button id="shrink">Shrink</button>
<script>
var x = document.getElementById('shrink');
var img = document.getElementById('image');
x.addEventListener("click", shrnk);
function shrnk() {
img.style.width = 50;
img.syle.height = 25;
};
</script>
</body>
</html>
Rather then using img.style just set the width and height values of the image.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="xyz.css" />
</head>
<body>
<img id="image" src="http://www.placehold.it/150" />
<button id="shrink">Shrink</button>
<script>
var x = document.getElementById('shrink');
var img = document.getElementById('image');
x.addEventListener("click", shrnk);
function shrnk() {
img.width = 50;
img.height = 25;
};
</script>
</body>
</html>
The width and height styles aren't numbers, they need units as well, like px for pixels. So
function shrnk() {
img.style.width = '50px';
img.style.height = '25px';
}
The only time you can omit the units is when you're setting them to 0, since that's the same regardless of the units.
If you'd like to use the style property you need to set the unit of the number you're talking about (ie. "px").
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="xyz.css" />
</head>
<body>
<img id="image" src="http://lorempixel.com/200/200" />
<button id="shrink">Shrink</button>
<script>
var x = document.getElementById('shrink');
var img = document.getElementById('image');
x.addEventListener("click", shrnk);
function shrnk() {
img.style.width = "50px";
img.style.height = "25px";
};
</script>
</body>
</html>

Creating shapes in an SVG

For my assignment, we create an SVG block and the user would input a number, and we add that number of squares to the svg block in random positions within the svg block. My code isn't working.
Here's my html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="http://cmpt165.csil.sfu.ca/js/jquery-3.1.0.js"></script>
<script src="http://cmpt165.csil.sfu.ca/js/raphael-2.1.4.js"></script>
<script src="logic.js"></script>
<link rel="stylesheet" href="style.css" />
<title>Exercise 10</title>
</head>
<body>
<h1>Exercise 10</h1>
<div id="svg1"></div>
<div class="form">Add how many?
<input type="text" id="howmany" />
<button id="more">Add More</button></div>
<div id="svg2"></div>
<div class="form">
<button id="another">Add Another</button>
</div>
</body>
</html>
Here's my Javascript:
var num_squares, x, y;
num_squares = $('#howmany').val()
add_more = function() {
for (count = 0;count < num_squares;count += 1)
{
x = Math.random() * 180
y = Math.random() * 180
r = paper.rect(x, y, 20, 20)
filled = {
'fill': '#ddf'
}
r.attr(filled)
}
}
setup = function() {
paper = Raphael('svg1', 200, 200)
add_more()
}
jQuery(document).ready(setup)
Here's my CSS:
#svg1 {
border: black;
}
You initialise num_squares outside the function i.e. on document load. This is before anyone's typed in a number so num_squares is always empty and therefore your loop doesn't do anything. You also aren't calling add_more when the button is pressed.
add_more = function() {
var num_squares, x, y;
num_squares = $('#howmany').val();
for (count = 0;count < num_squares;count += 1)
{
x = Math.random() * 180
y = Math.random() * 180
r = paper.rect(x, y, 20, 20)
filled = {
'fill': '#ddf'
}
r.attr(filled)
}
}
setup = function() {
paper = Raphael('svg1', 200, 200)
}
jQuery(document).ready(setup)
#svg1 {
border: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="http://cmpt165.csil.sfu.ca/js/jquery-3.1.0.js"></script>
<script src="http://cmpt165.csil.sfu.ca/js/raphael-2.1.4.js"></script>
<script src="logic.js"></script>
<link rel="stylesheet" href="style.css" />
<title>Exercise 10</title>
</head>
<body>
<h1>Exercise 10</h1>
<div id="svg1"></div>
<div class="form">Add how many?
<input type="text" id="howmany">
<button id="more" onclick="add_more()">Add More</button></div>
<div id="svg2"></div>
<div class="form">
<button id="another">Add Another</button>
</div>
</body>
</html>

script no longer updating the page

I have the following html page which displays a picture at a random location and updates it every 10 seconds :
<!DOCTYPE html>
<html>
<head>
<title>Domoos | Screen saver screen</title>
<meta http-equiv="refresh" content="10">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<meta http-equiv="pragma" content="no-cache">
<link rel="stylesheet" type="text/css" href="css/mystyle_saver.css" />
<script type="text/javascript" src="scripts/date_time.js"></script>
<script type="text/javascript">
function init() {
var xmin = 0;
var xmax = 890;
var ymin = 0;
var ymax = 430;
var xCoord = Math.floor((Math.random()*xmax)+xmin);
var yCoord = Math.floor((Math.random()*ymax)+ymin);
var xCoordStr = xCoord.toString() + "px";
var yCoordStr = yCoord.toString() + "px";
document.getElementById("randomPlacement").style.left = xCoordStr;
document.getElementById("randomPlacement").style.top = yCoordStr;
}
</script>
</head>
<body onload="init();">
<div style="position:absolute" id="randomPlacement">
<p><img src="assets/pictures/texte_sortie_veille.png" alt ="" style="width:60px;height:60px;"></p>
</div>
</body>
</html>
It works very well. Now, I would like to add two 'div' tags so I could display the date and the time. So, I updated the body tag as follows (the rest of the page remains unchanged) :
<body onload="init();">
<div style="position:absolute" id="randomPlacement">
<p><img src="assets/pictures/texte_sortie_veille.png" alt ="" style="width:60px;height:60px;"></p>
</div>
<div id="date">
<script type="text/javascript">window.onload = getDate('date');</script>
</div>
<div id="time">
<script type="text/javascript">window.onload = getTime('time');</script>
</div>
</body>
The problem by doing so is that the image is never displayed at a random location. What am I missing and hopefully how can I solve the issue? I have added an extract of the console in Chrome.
Thanks a lot for your help.
replace
<div id="date">
<script type="text/javascript">window.onload = getDate('date');</script>
</div>
<div id="time">
<script type="text/javascript">window.onload = getTime('time');</script>
</div>
with
<div id="time">
</div>
then in init()
function init() {
var xmin = 0;
var xmax = 890;
var ymin = 0;
var ymax = 430;
var xCoord = Math.floor((Math.random()*xmax)+xmin);
var yCoord = Math.floor((Math.random()*ymax)+ymin);
var xCoordStr = xCoord.toString() + "px";
var yCoordStr = yCoord.toString() + "px";
document.getElementById("randomPlacement").style.left = xCoordStr;
document.getElementById("randomPlacement").style.top = yCoordStr;
document.getElementById("date").innerhtml=getDate('date');
document.getElementById("time").innerhtml=gettime('time');
}

document.querySelector(...) is null error

For image upload in a cakephp project I used java-script.I added this js file in app\View\Layouts default.ctp
js code
document.querySelector('input[type=file]').addEventListener('change', function(event){
var files = event.target.files;
for (var i = 0; i < files.length; i++) {
if (files[i].type.match(/image.*/)) {
var reader = new FileReader();
reader.onload = function (readerEvent) {
var image = new Image();
image.onload = function (imageEvent) {
var imageElement = document.createElement('div');
imageElement.classList.add('uploading');
imageElement.innerHTML = '<span class="progress"><span></span></span>';
var progressElement = imageElement.querySelector('span.progress span');
progressElement.style.width = 0;
document.querySelector('form div.photos').appendChild(imageElement);
var canvas = document.createElement('canvas'),
max_size = 1200,
width = image.width,
height = image.height;
if (width > height) {
if (width > max_size) {
height *= max_size / width;
width = max_size;
}
} else {
if (height > max_size) {
width *= max_size / height;
height = max_size;
}
}
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(image, 0, 0, width, height);
var xhr = new XMLHttpRequest();
if (xhr.upload) {
// Update progress
xhr.upload.addEventListener('progress', function(event) {
var percent = parseInt(event.loaded / event.total * 100);
progressElement.style.width = percent+'%';
}, false);
xhr.onreadystatechange = function(event) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
imageElement.classList.remove('uploading');
imageElement.classList.add('uploaded');
imageElement.style.backgroundImage = 'url('+xhr.responseText+')';
console.log('Image uploaded: '+xhr.responseText);
} else {
imageElement.parentNode.removeChild(imageElement);
}
}
}
xhr.open('post', 'process.php', true);
xhr.send(canvas.toDataURL('image/jpeg'));
}
}
image.src = readerEvent.target.result;
}
reader.readAsDataURL(files[i]);
}
}
event.target.value = '';
I have checked there are no problem.
now in add.ctp file I adder
<input type="file" multiple />
In output I am seeing the file type field.Now when I clicked on this field and upload a image then mojila bug given me a error.That is
document.querySelector(...) is null error
I have no idea about this error.In here why saying queryselector is null?
document.querySelector() behaves similarly to the jQuery.(document).ready() method. When the DOM is ready, the selector returns the object.
I would suggest you call all JS script bottom of the page.
To make sure that your DOM is ready you could add this to your JS file.
// my-script.js
document.addEventListener("DOMContentLoaded", function() {
// this function runs when the DOM is ready, i.e. when the document has been parsed
document.querySelector('input[type=file]')
.addEventListener('change', function(event){
...
}
});
This way you could call your js files from wherever you like. Please take a look to this superb answer to get further insight on these matters.
Also take a look at this other Google rule.
file.js
const heading1 = document.querySelector(".heading1");
console.log(heading1);
Solution 1
Use defer (best & recommended way):
<!DOCTYPE html>
<html lang="en">
<head>
<script src="./file.js" defer></script>
<title>Document</title>
</head>
<body>
<h1 class="heading1">Hello World 1</h1>
</body>
</html>
Solution 2
Place your JavaScript in bottom before closing body tag
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<h1 class="heading1">Hello World 1</h1>
<script src="./file.js"></script>
</body>
</html>
I suggest writing your <script type="text/javascript" src="your js file"></script> in body, before the closing tag
There is now another "better" way to address this issue.
put your scripts in the head tag and add the defer attribute.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<script src="main.js" defer></script>
</head>
<body>
yoyoyo
</body>
</html>
you can read more about it here and here
TLDR (may be inaccurate and misleading so read the sources above!):
the defer attribute tells the browser to load the file but hold off its execution until the dom is ready, which is close to the behavior you implicitly get when you put the script tag at the bottom of the body tag, the difference being that in the old way you have to wait for the whole body tag to be parsed until you start downloading the script tag.
I ran into this issue where I was trying to do (slimmed down for simplicity):
<script type="text/javascript">
var svg = document.querySelector('svg');
console.log(svg);
</script>
on an element in the <body>:
<svg id="svg" viewBox="0 0 120 120" width="500px" height="500px"></svg>
Once I added jQuery and moved my lines inside of a $(document).ready(), it was fine:
<script type="text/javascript" src="jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var svg = document.querySelector('svg');
console.log(svg);
});
</script>
Here's a quick fix. I was trying to effect some changes in my HTML page using DOM and was getting this error. The problem was I linked my Javascript file inside the head tag of the HTML page, when I changed that and linked it at the body just before the closing body tag, it worked!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Soft dog</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#3.4.1/dist/css/bootstrap.min.css"
integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
<link rel="stylesheet" href="landing.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Cormorant+SC:wght#300&family=Edu+VIC+WA+NT+Beginner&display=swap"
rel="stylesheet">
</head>
<body>
<div class="container">
<h2 id="newBrand">Welcome to SOFTDOG</h2>
<p><em>property of soft 6</em></p>
<a id="ceo" href="home.html"><img src="softdogmerch1.jpg" alt="check network"></a>
<p id="enterstatement">Please<a href="home.html">
<P><span>ENTER HERE</span></P>
</a><span>to feed your eyes and fill your wardrobe</span>
</p>
<label for="emailinput">email:</label>
<input id="emailinput" type="email" name="useremail" placeholder="user#email.com" required>
<label for="passwordinput">password:</label>
<input id="passwordinput" type="password" name="userpassword" placeholder="" required>
<input id="clickme" type="submit" name="login" value="log in">
<input id="clickme" type="submit" name="signup" value="sign up">
</div>
<script src="landing.js"></script>
</body>
</html>

Categories

Resources