<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>JavaScript</title>
<meta name="description" content="page description">
<meta name="author" content="discoveryvip">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="css/ptc.css">
<canvas id= "canvas" style= "border:1px solid; position:absolute; ">
</canvas>
<div id="sprite"></div>
<style>
#sprite {
width: 135px;
height: 100px;
background-image: url("images/spritesheet.png");
position:absolute;
bottom:1000px;
left:220px;
transition: all 2s;
animation: run 1s steps(5) infinite, slide 4s steps(100) infinite;
margin-right : 100%;
}
#keyframes run {
100% { background-position: -700px;}
}
#keyframes slide {
100% { margin-right: 135px;}
#keyframes slide {
100% { margin-left: -140px;
}
</style>
<script>
var sprite = document.getElementById("sprite");
var canvas = document.querySelector("canvas");
var ctx= canvas.getContext("2d");
sprite.style.top = 30 + "px" ;
sprite.style.left = 140 + "px";
sprite.style.height = 100 + "px";
sprite.style.width = 1067 ;
sprite.style.height = 640 ;
document.body.onkeyup = function() {
var e = event.keyCode,
charTop = parseInt(sprite.style.top),
charLeft = parseInt(sprite.style.left);
if (e == 40) { //down function
sprite.style.top = (parseInt(sprite.style.top)) + 20 + "px";
} else if (e == 37) { //left function
sprite.style.left = (parseInt(sprite.style.left)) - 20 + "px";
} else if (e == 39) { //right function
sprite.style.left = (parseInt(sprite.style.left)) + 20 + "px";
} else if (e == 38) { //up function
sprite.style.top = (parseInt(sprite.style.top)) - 20 + "px";
}
}
</script>
I am having trouble making the sprite collide with the walls of
the canvas.
The sprite has been animated through css but it always escapes the canvas walls. I have done some research on collision detection and most code include setting up x and y positions of an object and putting in if statements to check whether it touches the canvas walls but I can't understand how to implement that code onto this sprite.Can anyone please be kind enough to put up an example.
I am still new to javascript and have been at this for weeks.
How about just moving it back if you hit the limit at your move?
} else if (e == 37) {
//left function
sprite.style.left = (parseInt(sprite.style.left)) - 20 + "px";
if(sprite.style.left < 0)
{
sprite.style.left + 20;
}
}
On the right function compare sprite left position + sprite width to canvas width.
Related
I made a game where you need to click the image on the left side of the screen that you do not see on the opposite side to get to the next level. For some reason, when you click any image on the left side you still go to the next level. When you click the wrong image it should say game over. Right now it only does that when the whitespace is clicked. Any tips?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Matching Game</title>
<style>
img {
position: absolute;
}
div {
position: absolute;
width: 500px;
height: 500px;
}
#rightSide {
left: 500px;
border-left: 1px solid;
}
</style>
</head>
<body onload="generateFaces()">
<h1>Matching Game</h1>
<p>Click on the extra smiling face on the left.</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
<script >
let numberOfFaces = 5;
const theLeftSide = document.querySelector("#leftSide");
const theRightSide = document.querySelector("#rightSide");
function generateFaces() {
for (let i = 0; i < numberOfFaces; i++) {
let face = document.createElement("img");
face.src = 'images/smile.png';
const randomTop = Math.floor(Math.random() * 400) + 1;
const randomLeft = Math.floor(Math.random() * 400) + 1;
face.style.top = randomTop + 'px';
face.style.left = randomLeft + 'px';
theLeftSide.appendChild(face);
theLeftSide.lastChild.addEventListener('click', nextLevel);
document.body.addEventListener('click', gameOver);
}
const leftSideImages = theLeftSide.cloneNode(true);
leftSideImages.removeChild(leftSideImages.lastChild);
theRightSide.appendChild(leftSideImages);
function nextLevel(event) {
event.stopPropagation();
numberOfFaces += 5;
while (theLeftSide.firstChild) {
theLeftSide.removeChild(theLeftSide.firstChild);
}
while (theRightSide.firstChild) {
theRightSide.removeChild(theRightSide.firstChild);
}
generateFaces();
}
function gameOver() {
alert('Game Over!');
document.body.removeEventListener('click', gameOver);
theLeftSide.lastChild.removeEventListener('click', nextLevel);
}
}
</script>
</body>
</html>
notice
for (let i = 0; i < numberOfFaces; i++) {
let face = document.createElement("img");
...
theLeftSide.appendChild(face);
// you do this in every loop
theLeftSide.lastChild.addEventListener('click', nextLevel);
}
put the theLeftSide.lastChild.addEventListener('click', nextLevel); outside loop for it to work
I'm trying to add collision detection in my draggable code which works pretty well I guess ,but when I'm trying to drag the orange rectangle above the green one nothing happens.
Is my collision logic right ?
Here is what I tried to do.
//HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href = "stl.css" rel = "stylesheet" type = "text/css">
</head>
<body>
<div class="item1"></div>
<div class="item2"></div>
<script src = "js.js" type = "text/javascript"></script>
</body>
</html>
I used getBoundingClientRect() to get the position of the rectangles.
//JAVASCRIPT code
const el1 = document.querySelector(".item1");
const el2 = document.querySelector(".item2");
var rect1,rect2;
rect2 = el2.getBoundingClientRect();
el1.addEventListener("mousedown", mousedown);
function mousedown(e) {
window.addEventListener("mousemove", mousemove);
window.addEventListener("mouseup", mouseup);
let prevX = e.clientX; // x cursor position
let prevY = e.clientY;//y cursor position
function mousemove(e) {
let newX = prevX - e.clientX;
let newY = prevY - e.clientY;
rect1 = el1.getBoundingClientRect();
el1.style.left = rect1.left - newX + "px";
el1.style.top = rect1.top - newY + "px";
prevX = e.clientX;
prevY = e.clientY;
//a simple rectangle collision logic funcion
if (rect1.left < rect2.left + rect2.weight &&
rect1.left + rect1.weight > rect2.left &&
rect1.top < rect2.top + rect2.height &&
rect1.height + rect1.top > rect2.top)
{
item2.style.color="#FF0006";
}
}
//function which stops the mousedown event
function mouseup() {
window.removeEventListener("mousemove", mousemove);
window.removeEventListener("mouseup", mouseup);
}
}
I know that item1 require absolute position for draggable action
//CSS code
.item1{
height:50px;
width:50px;
position:absolute;
background:orange;
}
.item2{
height:220px;
width:220px;
position:absolute;
background:green;
top:300px;
left:500px;
z-index:-2;
}
//JAVASCRIPT code
const el1 = document.querySelector(".item1");
const el2 = document.querySelector(".item2");
var rect1,rect2;
rect2 = el2.getBoundingClientRect();
el1.addEventListener("mousedown", mousedown);
function mousedown(e) {
window.addEventListener("mousemove", mousemove);
window.addEventListener("mouseup", mouseup);
let startX = e.clientX; // x cursor position
let startY = e.clientY; //y cursor position
const { left: rectX, top: rectY } = el1.getBoundingClientRect();
function mousemove(e) {
rect1 = el1.getBoundingClientRect();
const diffX = e.clientX - startX;
const diffY = e.clientY - startY;
el1.style.left = (rectX + diffX) + "px";
el1.style.top = (rectY + diffY) + "px";
// https://gamedev.stackexchange.com/questions/586/what-is-the-fastest-way-to-work-out-2d-bounding-box-intersection
// function IntersectRect(r1:Rectangle, r2:Rectangle):Boolean {
// return !(r2.left > r1.right
// || r2.right < r1.left
// || r2.top > r1.bottom
// || r2.bottom < r1.top);
// }
//a simple rectangle collision logic funcion
if (rect1.left < rect2.left + rect2.width &&
rect1.left + rect1.width > rect2.left &&
rect1.top < rect2.top + rect2.height &&
rect1.top + rect1.height > rect2.top)
{
el2.style.background ="#FF0006";
} else {
el2.style.background ="black"; // put original color
}
}
//function which stops the mousedown event
function mouseup() {
window.removeEventListener("mousemove", mousemove);
window.removeEventListener("mouseup", mouseup);
}
}
//CSS code
.body {
position: relative;
}
.item1{
height:50px;
width:50px;
position:absolute;
background:orange;
}
.item2{
height:120px;
width:120px;
position:absolute;
background:green;
top:300px;
left:500px;
z-index:-2;
}
//HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href = "stl.css" rel = "stylesheet" type = "text/css">
</head>
<body>
<div class="item1"></div>
<div class="item2"></div>
<script src = "js.js" type = "text/javascript"></script>
</body>
</html>
I've created an article with a red background, you can move it using WASD keys, however, the real trouble comes in when I try to create a diagonal movement (for ex, if W and D are pressed, the article should go to the top right corner), it doesn't seem to work:
document.body.addEventListener('keypress', function(event) {
var oldLeft = getComputedStyle(document.body).left,
newLeft;
var oldTop = getComputedStyle(document.body).top,
newTop;
oldLeft = parseInt(oldLeft, 10);
oldTop = parseInt(oldTop, 10);
console.log(event);
if ( event.key == 'a') {
newLeft = oldLeft - 10;
}
else if ( event.key == 'd') {
newLeft = oldLeft + 10;
}
else if (event.key == 'w') {
newTop = oldTop - 10;
}
else if (event.key == 's') {
newTop = oldTop + 10;
}
//HERE
if ((event.key =='w') || (event.key == 'd')) {
newLeft = oldLeft + 10;
newTop = oldTop - 10;
}
document.body.style.left = newLeft + 'px';
document.body.style.top = newTop + 'px';
});
article {
width: 33.75em;
padding: 1.5em;
margin: 0 auto;
background: #f6be00;
/*border: 4px solid white;*/
border-radius: 1.25em;
position: relative;
left: 0;
}
body {
position: relative;
background: red;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/styles.css">
<title>Javascript</title>
</head>
<body>
<article class="article">
<ul id="browser">
</ul>
<ul id="user">
</ul>
</article>
<script src="javascript/main.js"></script>
</body>
</html>
It goes to the top right corner but that happens even when I don't press W and D at the same time.
Use keydown events to collect keys to an array, and keyup events to wait until all keys are un-pressed to execute the changes:
var clicked = {};
document.body.addEventListener('keydown', function(event) {
clicked[event.key] = false; // collect keys an init as false
});
document.body.addEventListener('keyup', function(event) {
clicked[event.key] = true; // change keys to true
// if not all keys are true don't execute anything
if (!Object.values(clicked).every(Boolean)) return;
var left = parseInt(getComputedStyle(document.body).left, 10);
var top = parseInt(getComputedStyle(document.body).top, 10);
// get the clicked keys
const keys = Object.keys(clicked);
// iterate them and change the values
keys.forEach(function(key) {
switch (key) {
case 'a':
{
left -= 10;
break;
}
case 'd':
{
left += 10;
break;
}
case 'w':
{
top -= 10;
break;
}
case 's':
{
top += 10;
break;
}
}
});
clicked = {}; // clear clicked keys
document.body.style.left = left + 'px';
document.body.style.top = top + 'px';
});
article {
width: 33.75em;
padding: 1.5em;
margin: 0 auto;
background: #f6be00;
/*border: 4px solid white;*/
border-radius: 1.25em;
position: relative;
left: 0;
}
body {
position: relative;
background: red;
}
<article class="article"></article>
var arrow = document.getElementById("arrow");
function shot() {
var arrows = document.createElement("div");
document.body.appendChild(arrows);
arrows.style.backgroundColor = "black";
arrows.style.height = "80" + "px";
arrows.style.width = "3" + "px";
var arrowX = parseInt(document.arrow.style.left);
var arrowY = parseInt(document.arrow.style.top);
document.arrows.style.left = arrowX + "px";
document.arrows.style.top = arrowY + "px";
};
When I run it and click button which runs function shot it says it cannot read property "style" of undefined. It also spawns a new element on position it would spawn without any position defining.
Yep, my ids are correct.
Html:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div id="arrow"><div>
<button id="button" onclick="shot();"> Shot! </button>
</body>
</html>
CSS:
#arrow {
background-color: black;
height: 80px;
width: 1.5px;
position: relative;
left: 0px;
top: 0px;
}
Here is full project JS, which u dont need. Its not complete. There is button faster but it doesnt work, idk why. It should be archery game
var arrow = document.getElementById("arrow");
var arrowPos = -50;
var speed = 1000;
var speed2 = speed/100;
function arrow_move_right() {
arrowPos += 1;
arrow.style.left = arrowPos + "px";
if (arrowPos >= 280) {
return arrow_move_left()
}
else {
setTimeout(arrow_move_right, speed2);
};
};
function arrow_move_left() {
arrow = document.getElementById("arrow");
arrowPos -= 1;
arrow.style.left = arrowPos + "px";
if (arrowPos <= -50) {
return arrow_move_right()
}
setTimeout(arrow_move_left, speed2);
};
function faster() {
speed -= 100;
alert(speed)
}
function shot() {
var arrows = document.createElement("div");
document.body.appendChild(arrows);
arrows.style.backgroundColor = "black";
arrows.style.height = "80" + "px";
arrows.style.width = "1.5" + "px";
var arrowX = parseInt(arrow.style.left);
var arrowY = parseInt(arrow.style.top);
alert(arrowX);
alert(arrowY);
// arrows.style.left = arrowX;
// arrows.style.top = arrowY;
arrows.style.pos = "relative";
arrows.style.top = -50 + "px";
};
Hope this is what you are looking for!
var arrow = document.getElementById("arrow");
function shot() {
var arrows = document.createElement("div");
document.body.appendChild(arrows);
arrows.style.backgroundColor = "blue";
arrows.style.height = "80px";
arrows.style.width = "3px";
arrows.style.position = "absolute";
arrows.style.top = arrow.offsetTop + "px";
arrows.style.left = arrow.offsetLeft + "px";
};
#arrow {
height: 80px;
width: 3px;
background: black;
position: relative;
-webkit-animation: move 5s infinite; /* Safari 4.0 - 8.0 */
animation: move 5s infinite;
}
/* Styles for animating arrow */
/* Safari 4.0 - 8.0 */
#-webkit-keyframes move {
from {left: 0px;}
to {left: 400px;}
}
#keyframes move {
from {left: 0px;}
to {left: 400px;}
}
<div id="arrow"></div>
<button id="button" onclick="shot();"> Shot! </button>
Here is what I mean....
var arrow = document.getElementById("arrow");
function shot() {
var arrows = document.createElement("div");
document.body.appendChild(arrows);
arrows.style.backgroundColor = "black";
arrows.style.height = "80" + "px";
arrows.style.width = "3" + "px";
var arrowX = parseInt(arrow.style.left);
var arrowY = parseInt(arrow.style.top);
arrows.style.left = arrowX + "px";
arrows.style.top = arrowY + "px";
};
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<div id="arrow"><div>
<button id="button" onclick="shot();"> Shot! </button>
</body>
</html>
Everything works like a charm locally when red block hits black block, it refreshes instantly (coming to start position). I can't figure out why the website doesn't refresh after collision (game over) on the remote server. Sometimes it needs few seconds to react or it requires moving the player position.
Found a tip to replace
location.reload(true);
with
location.href = location.href;
but it doesn't work at all in my case.
Fiddle to inspect my code: https://jsfiddle.net/32o8q5gz/1/
Remote host: https://stacho163.000webhostapp.com/
HTML code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Obulis 2</title>
<link rel="stylesheet" type="text/css" href="gameStyle.css">
</head>
<body>
<div class="game-content">
<h1>Obulis 2</h1>
<canvas id="game-window">
</canvas>
</div>
<script src="gameScript.js"></script>
</body>
</html>
CSS code:
* {
margin: 0;
padding: 0;
}
body {
background-color: #000;
}
.game-content {
position: relative;
width: 100vw;
height: 100vh;
}
h1 {
position: absolute;
color: red;
font-size: 50px;
left: 50%;
top: 1.5%;
transform: translate(-50%);
}
#game-window {
position: absolute;
width: 90vw;
height: 90vw * 16/9;
top: 50%;
left: 50%;
transform: translate(-50%, -46%);
background-color: gray;
}
JS code:
// js game script //
let canvas = document.getElementById('game-window');
let ctx = canvas.getContext('2d');
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
let left = false;
let up = false;
let right = false;
let down = false;
let player = {
size: 50,
posX: (canvas.width / 2) - 25,
posY: (canvas.height / 2) - 25,
speed: 5
}
let obstacle = {
size: Math.round((Math.random() * 100) + 50),
posX: Math.round((Math.random() * 1200) + 50),
posY: -50,
speed: Math.round((Math.random() * 10) + 1)
}
function drawPlayer() {
ctx.fillStyle = "red";
ctx.fillRect(player.posX, player.posY, player.size, player.size);
}
function drawObstacle() {
ctx.fillStyle = "#000";
ctx.fillRect(obstacle.posX, obstacle.posY, obstacle.size, obstacle.size);
obstacle.posY += obstacle.speed;
}
function darknessCollision() {
if (player.posX < 0 ||
player.posY < 0 ||
player.posX > canvas.width - player.size ||
player.posY > canvas.height - player.size) {
location.reload(true);
}
}
function obstacleCollision() {
if (player.posX <= obstacle.posX + obstacle.size &&
player.posY <= obstacle.posY + obstacle.size &&
player.posX + player.size >= obstacle.posX &&
player.posY + player.size >= obstacle.posY) {
location.href = location.href;
}
}
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function move() {
if (left) {
player.posX -= player.speed;
}
if (up) {
player.posY -= player.speed;
}
if (right) {
player.posX += player.speed;
}
if (down) {
player.posY += player.speed;
}
}
document.onkeydown = function (e) {
if (e.keyCode == 37) left = true;
if (e.keyCode == 38) up = true;
if (e.keyCode == 39) right = true;
if (e.keyCode == 40) down = true;
e.preventDefault();
}
document.onkeyup = function (e) {
if (e.keyCode == 37) left = false;
if (e.keyCode == 38) up = false;
if (e.keyCode == 39) right = false;
if (e.keyCode == 40) down = false;
e.preventDefault();
}
setInterval (function game() {
clearCanvas();
drawObstacle();
drawPlayer();
darknessCollision();
obstacleCollision();
move();
}, 10);
Thanks in advance for your tips! :)
This is a completely normal behavior.
When you refresh a local website, the only delay is the time spent reading the website again from your computer’s memory, and even that can get much faster for many reasons.
However, refreshing an online website, usually (if not cached), requires a “round trip time” from your computer to the server, which is sometimes costing few seconds.
If refreshing the page is for the sake of getting new updates, unfortunately there is no way to reduce the refreshing time. But, if you just need to start the website one more time, you can either use JavaScript history methods as mentioned, or have a JavaScript function that returns you to the first state without the need to refresh at all.
Hope this helps.
Two other options:
history.go(0);
And:
window.location.href = window.location.href;