I'm making a website for my digital assessment for school & need a hand with my javascript game which is being coded inside the <canvas> element. So pretty much I've got this little drone being controlled by the "forward", "left" , "right" & "back" buttons to move the drone around, since my background is a flat 2d image with walls on it I've made 100% transparent boxes and placed them over the wall areas to mimic the walls being there.
I just can't find any help with the IF statement where the drone touches the invisible box it puts it back to 43X 110Y... the code is below if you think you can help!! :)
(MyGamePiece is the drone, myHitBox is the invisible image.)
<style>
canvas {
border:1px solid #d3d3d3;
background-color: #f1f1f1;
}
</style>
</head>
<body onload="startGame()">
<script>
var myGamePiece;
var myBackground;
var myHitBox;
var myHitBox1;
var myHitBox2;
var myHitBox3;
var myHitBox4;
var myHitBox5;
function startGame() {
myGamePiece = new component(50, 50, "img/forward.gif", 43, 110, "image");
myHitBox = new component(275, 20, "img/hitbox.png", 250, 169, "image");
myHitBox1 = new component(30, 100, "img/hitbox.png", 250, 170, "image");
myHitBox2 = new component(280, 25, "img/hitbox.png", 0, 80, "image");
myHitBox3 = new component(30, 100, "img/hitbox.png", 120, 80, "image");
myHitBox4 = new component(145, 25, "img/hitbox.png", 375, 80, "image");
myHitBox5 = new component(30, 100, "img/hitbox.png", 375, 0, "image");
myBackground = new component(650, 270, "img/MAP.jpg", 0, 0, "image");
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 650;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
stop : function() {
clearInterval(this.interval);
}
}
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
}
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width, this.height);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
}
function updateGameArea() {
myGameArea.clear();
myBackground.newPos();
myBackground.update();
myGamePiece.newPos();
myGamePiece.update();
myHitBox.newPos();
myHitBox.update();
myHitBox1.newPos();
myHitBox1.update();
myHitBox2.newPos();
myHitBox2.update();
myHitBox3.newPos();
myHitBox3.update();
myHitBox4.newPos();
myHitBox4.update();
myHitBox5.newPos();
myHitBox5.update();
}
function move(dir1) {
if (dir1 == "down") {myGamePiece.speedY = 5; myGamePiece.image.src = "img/forward.gif";}
else if (dir1 == "up") {myGamePiece.speedY = -5; myGamePiece.image.src = "img/back.gif";}
else if (dir1 == "right") {myGamePiece.speedX = 5; myGamePiece.image.src = "img/right.gif";}
else if (dir1 == "left") {myGamePiece.speedX = -5; myGamePiece.image.src = "img/left.gif";}
}
function clearmove() {
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
}
</script>
<div style="text-align:center;width:480px;">
<button onmousedown="move('up')" onmouseup="clearmove()" ontouchstart="move('up')">UP</button><br><br>
<button onmousedown="move('left')" onmouseup="clearmove()" ontouchstart="move('left')">LEFT</button>
<button onmousedown="move('right')" onmouseup="clearmove()" ontouchstart="move('right')">RIGHT</button><br><br>
<button onmousedown="move('down')" onmouseup="clearmove()" ontouchstart="move('down')">DOWN</button>
</div>
The alternative solution I mentioned in the comments, as you were interested:
If you have a complex background, you can create a simple map equivalent.
E.g. This background:
Would use this simple layout map:
Then have a second invisible canvas where you run something along these lines:
(Rough outline, will need to be edited to work for you)
var x = <drone X position>;
var y = <drone Y position>;
var colour = secondCanvasContext.getImageData(x, y, 1, 1).data;
if(colour[0] == 0 && colour[1] == 0 && colour[2] == 0){
// Your drone is on a black background, so it's not hitting a wall
}
Related
I need help finishing a function that shoots bullets after pressing 'space'.
I tried using these
var b = new bullet();
var bullets = []
bullets.push(b)
Then a for loop like this:
for (var i = 0; i < 6; i++) {
but I cant get it to work. Basically a function that every time a bullet is made, it is stored in an array then space loops through the array making new bullets on space press.
fiddle: https://jsfiddle.net/tmanrocks999/7mLpo8uj/652/
code:
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
canvas {
border:4px solid #d3d3d3;
background-color: #f1f1f1;
}
</style>
</head>
<body onload="startGame()">
<script>
var myGamePiece;
var endGoalPiece;
var myEnemy1;
var bullet;
var myEnemy1Hp = 10;
var damage = 1;
var playerExp = 0;
function startGame() {
myGameArea.start();
myGamePiece = new component(30, 30, "red", 0, 240);
endGoalPiece = new component(30, 30, "black", 450, 240);
myEnemy1 = new component(30, 30, "green", 200, 240);
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 480;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 20);
window.addEventListener('keydown', function (e) {
myGameArea.key = e.keyCode;
})
window.addEventListener('keyup', function (e) {
myGameArea.key = false;
})
},
clear : function(){
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function component(width, height, color, x, y) {
this.gamearea = myGameArea;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
//this.gravity = 0.05;
//this.gravitySpeed = 0;
this.x = x;
this.y = y;
this.color = color;
this.update = function() {
ctx = myGameArea.context;
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.newPos = function() {
this.gravitySpeed += this.gravity;
this.x += this.speedX;
this.y += this.speedY; //+ this.gravitySpeed;
}
}
}
function jump() {
myGamePiece.gravitySpeed=-1;
}
}
function shootGun(){
bullet = new component(11, 5, "blue", myGamePiece.x+27 , myGamePiece.y+13 );
bullet.newPos();
bullet.speedX=1;
}
function updateGameArea() {
myGameArea.clear();
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
if (myGameArea.key && myGameArea.key == 37) {myGamePiece.speedX = -1; }//left
if (myGameArea.key && myGameArea.key == 39) {myGamePiece.speedX = 1; }//right
if (myGameArea.key && myGameArea.key == 38) {myGamePiece.gravitySpeed = -1; }//jump
if (myGameArea.key && myGameArea.key == 32) {shootGun()}//shoot gun
//if (myGameArea.key && myGameArea.key == 40) {myGamePiece.speedY = 1; }// down
myEnemy1.update();
endGoalPiece.update();
myGamePiece.newPos();
myGamePiece.update();
bullet.newPos();
bullet.update();
}
</script>
<p>use the arrow keys on you keyboard to move the red square.</p>
<span id="myEnemy1Hp">10</span> <br>
<span id="playerExp">0<span><br> / <span id = "playerMaxExp">100</span>
</body>
</html>
I expect on space press for bullets to keep being created by looping through the array but at the moment after space press only 1 bullet is made and position is reset every time you press space ( I know why this is I don't need it explained).
How can I get the illusion of a shooter.
Take a look at this code:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>STACKOVERFLOW</title>
<style>
canvas {
border: 4px solid #d3d3d3;
background-color: #f1f1f1;
}
</style>
</head>
<body onload="startGame()">
<p>use the arrow keys on you keyboard to move the red square.</p>
<span id="myEnemy1Hp">10</span> <br>
<span id="playerExp">0<span><br> / <span id = "playerMaxExp">100</span>
<script>
var myGamePiece;
var endGoalPiece;
var myEnemy1;
var bullets = [];
var myEnemy1Hp = 10;
var damage = 1;
var playerExp = 0;
function startGame() {
myGameArea.start();
myGamePiece = new component(30, 30, "red", 0, 240);
endGoalPiece = new component(30, 30, "black", 450, 240);
myEnemy1 = new component(30, 30, "green", 200, 240);
}
var myGameArea = {
canvas: document.createElement("canvas"),
start: function() {
this.canvas.width = 480;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 20);
window.addEventListener('keydown', function(e) {
myGameArea.key = e.keyCode;
})
window.addEventListener('keyup', function(e) {
myGameArea.key = false;
})
},
clear: function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function component(width, height, color, x, y) {
this.gamearea = myGameArea;
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
//this.gravity = 0.05;
//this.gravitySpeed = 0;
this.x = x;
this.y = y;
this.color = color;
this.update = function() {
ctx = myGameArea.context;
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.newPos = function() {
this.gravitySpeed += this.gravity;
this.x += this.speedX;
this.y += this.speedY; //+ this.gravitySpeed;
}
}
function jump() {
myGamePiece.gravitySpeed = -1;
}
function shootGun() {
let bullet = new component(11, 5, "blue", myGamePiece.x + 27, myGamePiece.y + 13);
bullet.newPos();
bullet.speedX = 1;
bullets.push( bullet );
}
function updateGameArea() {
myGameArea.clear();
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
if (myGameArea.key && myGameArea.key == 37) {
myGamePiece.speedX = -1;
} //left
if (myGameArea.key && myGameArea.key == 39) {
myGamePiece.speedX = 1;
} //right
if (myGameArea.key && myGameArea.key == 38) {
myGamePiece.gravitySpeed = -1;
} //jump
if (myGameArea.key && myGameArea.key == 32) {
shootGun()
} //shoot gun
//if (myGameArea.key && myGameArea.key == 40) {myGamePiece.speedY = 1; }// down
myEnemy1.update();
endGoalPiece.update();
myGamePiece.newPos();
myGamePiece.update();
bullets.forEach( (bullet)=> {
bullet.newPos()
bullet.update();
});
// bullet.newPos();
// bullet.update();
}
</script>
</body>
</html>
Codepen
I'm trying to make my "YellowTrack" var move, bu I'm getting crazy and i can't achieve it. I don't know why, but the "y" coordinate doesn't update, so It doesn't move. I've tried a lot of cases but any of them could solve the movement problen Could anybody help me? PD: Sorry for my bad code writing
The code is below:
function startGame() {
myGameLines1 = new DrawingLines(200, 0, 200, 600, "black");
myGameLines2 = new DrawingLines(350, 0, 350, 600, "black");
myGameLines3 = new DrawingLines(500, 0, 500, 600, "black");
myGameLines4 = new DrawingLines(650, 0, 650, 600, "black");
myGameLines5 = new DrawingLines(800, 0, 800, 600, "black");
myGameFinalLine = new FinalLine(100, 500, 800, 20, "purple");
myGameFixedSquare1 = new DrawingFixedSquares(171, 475, 60, 60, "yellow");
myGameFixedSquare2 = new DrawingFixedSquares(321, 475, 60, 60, "red");
myGameFixedSquare3 = new DrawingFixedSquares(471, 475, 60, 60, "#F34621");
myGameFixedSquare4 = new DrawingFixedSquares(621, 475, 60, 60, "blue");
myGameFixedSquare5 = new DrawingFixedSquares(771, 475, 60, 60, "green");
myGameArea.start();
YellowTrack = new DrawingFixedSquares(171, 200, 60, 60, "yellow");
animate(YellowTrack, canvas, ctx, startTime);
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 1000;
this.canvas.height = 600;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
var ctx = myGameArea.context;
var canvas = myGameArea.canvas;
function DrawingLines(x1, y1, x2, y2, color) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.update = function(){
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.lineWidth="2";
ctx.strokeStyle="black";
ctx.moveTo(this.x1,this.y1);
ctx.lineTo(this.x2,this.y2);
ctx.stroke();
}
}
function DrawingFixedSquares(x, y, width, height, color) {
this.height = height;
this.width = width;
this.x = x;
this.y = y;
this.update = function(){
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
function FinalLine(x, y, width, height, color) {
this.height = height;
this.width = width;
this.x = x;
this.y = y;
this.update = function(){
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
function updateGameArea() {
myGameArea.clear();
myGameLines1.update();
myGameLines2.update();
myGameLines3.update();
myGameLines4.update();
myGameLines5.update();
myGameFinalLine.update();
myGameFixedSquare1.update();
myGameFixedSquare2.update();
myGameFixedSquare3.update();
myGameFixedSquare4.update();
myGameFixedSquare5.update();
YellowTrack.update();
}
function animate(YellowTrack, canvas, ctx, startTime) {
var time = (new Date()).getTime() - startTime;
var linearSpeed = 100;
var newY = linearSpeed * time / 1000;
if(newY < canvas.height) {
YellowTrack.y = newY;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
requestAnimFrame(function() {
animate(YellowTrack, canvas, ctx, startTime);
});
}
setTimeout(function() {
var startTime = (new Date()).getTime();
animate(YellowTrack, canvas, ctx, startTime);
}, 1000);
Animating things on a canvas is quite easy with window.requestAnimationFrame.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: black;
}
canvas {
position: absolute;
margin: auto;
left: 0;
right: 0;
border: solid 1px white;
border-radius: 10px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="application/javascript">
// Anonymous closure to sandbox my code
void function() {
// Tells the JS engine to use strict syntax rules
// e.g. creating variables without var, let or const
// creates an error in strict mode
"use strict";
var canvasWidth = 180;
var canvasHeight = 160;
var canvas = null;
var ctx = null;
var mouse = {x: 0.0, y: 0.0};
var box = {x: 0.0, y: 0.0, width: 20, height: 20};
var boxMoveSpeed = 25.0;
// Called whenever the mouse moves
// (canvas.onmousemove can be used too)
window.onmousemove = function(e) {
if (canvas) {
// Gets the canvas' offset from the top left of the screen
var boundingRect = canvas.getBoundingClientRect();
mouse.x = e.clientX - boundingRect.left;
mouse.y = e.clientY - boundingRect.top;
}
}
// Game loop
function loop() {
// Tick (Update game logic)
box.x += (mouse.x - box.x - box.width * 0.5) / boxMoveSpeed;
box.y += (mouse.y - box.y - box.height * 0.5) / boxMoveSpeed;
// Render
ctx.fillStyle = "#333333";
ctx.fillRect(0,0,canvasWidth,canvasHeight);
ctx.lineWidth = 3;
ctx.strokeStyle = "black";
ctx.fillStyle = "darkred";
ctx.beginPath();
ctx.rect(box.x,box.y,box.width,box.height);
ctx.fill();
ctx.stroke();
// Handy function that loops this
// function at 60Hz (60 fps) for me.
requestAnimationFrame(loop);
}
// Called when the page finishes loading
// I treat it like a 'main method' you see
// in other languages
window.onload = function() {
canvas = document.getElementById("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
ctx = canvas.getContext("2d");
loop();
}
}();
</script>
</body>
</html>
function startGame() {
myGamePiece = new component(30, 30, "red", 10, 120);
myGameArea.start();
myWall = new defense(30, 150, "black", 90, 120)
myGameArea.start();
myWall2 = new defense(30, 150, "black", 180, 0)
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 338;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas,
document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width,
this.canvas.height);
}
}
function defense(width, height, color, x, y) {
this.width = width;
this.height = height;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.newPos = function(){
this.x;
this.y;
}
}
function component(width, height, color, x, y) {
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
}
There's my snippet of code please help me with my collision between the wall and square. I also have buttons to move the square if you need to know.
Here's some more code for your convenience just please get me a answer thanks in advance.
I know its a lot of code but its also not all of it so ifyou need anything else just ask thanks.
Adding addendum: This code will only check for square entity collisions, ie a tile based 2d style of game. This will not work in a 3d based graphic set, or do any sort of fine collision detection (against non square entities).
Without seeing more of your code, such as how you're rendering or managing state of the entities, you just need a function call during your update() method, wherever that may be.
The method I used in a hobby project several years ago, the collision logic looked like this (a function that would return just a boolean). This is just a jist I can give unless I see more of your code.
function isColliding(entity1, entity2) {
var e1top = entity1.y;
var e1bot = entity1.y + entity1.height;
var e1left = entity1.x;
var e1right = entity1.x + entity1.width;
var e2top = entity2.y;
var e2bot = entity2.y + entity2.height;
var e2left = entity2.x;
var e2right = entity2.x + entity2.width;
var collision = true;
if ((e1top > e2bot) || (e1bot < e2top) || (e1left > e2right) || (e1right < e2left))
collision = false;
return collision;
}
I've been trying to make objects scroll through the canvas, like when it goes down, it will come out of the top. I have got it working for the bottom and right sides, but it just gets stuck on the left and top side.
Here is what the code looks like in action
http://output.jsbin.com/gavuqo/
Here is my javascript code:
var count = 1;
var myGamePiece;
var myObstacle;
var myHealth;
var myScore;
function startGame() {
myGamePiece = new component(40, 40, "http://www.link", 10, 120, "image");
myObstacle = new component(60, 60, "http://www.link", 300, 120, "image");
myHealth = new component(60, 60, "http://www.link", 300, 100, "image");
myGameArea.start();
}
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 600;
this.canvas.height = 400;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
stop : function() {
clearInterval(this.interval);
}
};
function component(width, height, color, x, y, type) {
this.type = type;
if (type == "image") {
this.image = new Image();
this.image.src = color;
}
this.width = width;
this.height = height;
this.angle = Math.floor(Math.random() * 360) + 0 ;
this.speed = 1;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
if (type == "image") {
ctx.drawImage(this.image,
this.x,
this.y,
this.width, this.height);
} else {
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
this.newPos = function() {
if( this.x<=0 || this.x>=600){this.x = -this.speed * Math.sin(this.angle);}else{ this.x += this.speed * Math.sin(this.angle);
}
if( this.y<=0 || this.y>=400) {this.y = -this.speed * Math.cos(this.angle);}else{
this.y += this.speed * Math.cos(this.angle);}
}
//myObstacle.newPos();
this.newPosmain = function() {
this.x += this.speedX;
this.y += this.speedY;
};
this.crashWith = function(otherobj) {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var otherleft = otherobj.x;
var otherright = otherobj.x + (otherobj.width);
var othertop = otherobj.y;
var otherbottom = otherobj.y + (otherobj.height);
var crash = true;
if ((mybottom < othertop) ||
(mytop > otherbottom) ||
(myright < otherleft) ||
(myleft > otherright)) {
crash = false;
}
return crash;
};
}
function updateGameArea() {
if (myGamePiece.crashWith(myObstacle) && count==1) {
myObstacle = new component(60, 60, "http://www.link", 300, 120, "image");
count++;
myGamePiece = new component(80, 80, "http://www.link", 10, 120, "image");
} else {
myGameArea.clear();
myObstacle.update();
//myObstacle.wallBounce();
myObstacle.newPos();
myHealth.update();
myHealth.newPos();
//myHealth.wallBounce();
myGamePiece.newPosmain();
myGamePiece.update();
}
if(myGamePiece.crashWith(myObstacle) && count==2){
myObstacle = new component(60, 60, "http://www.link", 300, 120, "image");
myGamePiece = new component(100, 100, "http://www.link", 10, 120, "image");
count++;
}
if(myGamePiece.crashWith(myObstacle) && count==3){
myGamePiece = new component(500, 500, "#", 0, 0, "image");
myeGameArea.stop();
document.body.style.backgroundImage = "url('#')";
count=0;
}
if(myGamePiece.crashWith(myHealth) && count==1){
myGamePiece = new component(100, 100, "http://www.link", 10, 120, "image");
count=0;
count--;
}
if(myGamePiece.crashWith(myHealth) && count==2){
myGamePiece = new component(40, 40, "http://www.link", 10, 120, "image");
count--;
}
if(myGamePiece.crashWith(myObstacle) && count==0){
myObstacle = new component(60, 60, "http://www.link", 300, 120, "image");
myGamePiece = new component(100, 100, "http://www.link", 10, 120, "image");
count++;
}
if(myGamePiece.crashWith(myHealth) && count==0){
myGamePiece = new component(500, 500, "http://example.com", 0, 0, "image");
}
}
function moveup() {
myGamePiece.speedY = -2;
}
function movedown() {
myGamePiece.speedY = 2;
}
function moveleft() {
myGamePiece.speedX = -2;
}
function moveright() {
myGamePiece.speedX = 2;
}
function clearmove() {
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
}
Simply adjust either the x or y position to be opposite of the exit point. If it exits at the bottom then reset it to top minus diameter of the object without adjusting x, and so forth.
In generic code:
// dia = diameter of object (you may have to use different values for width/height)
if (x < -dia) x = width;
else if (x >= width) x = -dia;
if (y < -dia) y = height;
else if (y >= height) y = -dia;
Example
(click run again to change direction)
var ctx = c.getContext("2d"),
x = c.width * 0.5, y = c.height * 0.5,
dx = Math.max(2, Math.random() * 4),
dy = Math.max(2, Math.random() * 4),
dia = 10;
dx *= Math.random() < 0.5 ? -1 : 1;
dy *= Math.random() < 0.5 ? -1 : 1;
(function loop() {
ctx.clearRect(0,0,c.width,c.height);
ctx.fillRect(x, y, dia, dia);
x += dx;
y += dy;
if (x < -dia) x = c.width;
else if (x >= c.width) x = -dia;
if (y < -dia) y = c.height;
else if (y >= c.height) y = -dia;
requestAnimationFrame(loop)
})()
#c {border:1px solid #999}
<canvas id=c>
I am working on Browser game, and I wanted to make map where you can move around, fight with mobs, buy some stuff, but only map. Everything else will be in different pages.
So I made map with multiple images which are in loop.
It reads value world, x and y from database. I have made it work with ajax so the page doesnt refresh every time you move, but I wanted to make this map using Canvas.
$ystart = $y - 2;
$ymax = $y + 2;
$xstart = $x - 3;
$xmax = $x + 3;
for($y=$ystart;$y<=$ymax;$y++){
echo "<tr>";
for($x=$xstart;$x<=$xmax;$x++){
// echo "<td><img src=images/map/day/".$x."_".$y.".jpg width=100 height=100 border=0></td>\n";
if($x==$posx and $y==$posy){
echo "<td background=images/map/world_".$world."/".$y."_".$x.".jpg><img src=images/char.png width=100 height=100 border=0></td>";
} else{
echo "<td><img src=images/map/world_".$world."/".$y."_".$x.".jpg width=100 height=100 border=0></td>";
}
}
echo "</tr>";
}?>
I have done this so far
body {
margin: 0;
}
canvas {
border: 1px solid #d3d3d3;
background-color: #f1f1f1;
}
<body onload="startGame()">
<script>
var myGamePiece;
var myUpBtn;
var myDownBtn;
var myLeftBtn;
var myRightBtn;
function startGame() {
myGamePiece = new component(30, 30, "red", 10, 120);
myUpBtn = new component(30, 30, "blue", 50, 10);
myDownBtn = new component(30, 30, "blue", 50, 70);
myLeftBtn = new component(30, 30, "blue", 20, 40);
myRightBtn = new component(30, 30, "blue", 80, 40);
myGameArea.start();
}
var myGameArea = {
canvas: document.createElement("canvas"),
start: function() {
this.canvas.width = 480;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 20);
window.addEventListener('mousedown', function(e) {
myGameArea.x = e.pageX;
myGameArea.y = e.pageY;
})
window.addEventListener('mouseup', function(e) {
myGameArea.x = false;
myGameArea.y = false;
})
window.addEventListener('touchstart', function(e) {
myGameArea.x = e.pageX;
myGameArea.y = e.pageY;
})
window.addEventListener('touchend', function(e) {
myGameArea.x = false;
myGameArea.y = false;
})
window.addEventListener('keydown', function(e) {
myGameArea.key = e.keyCode;
})
window.addEventListener('keyup', function(e) {
myGameArea.key = false;
})
},
clear: function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function component(width, height, color, x, y) {
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.clicked = function() {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var clicked = true;
if ((mybottom < myGameArea.y) || (mytop > myGameArea.y) || (myright < myGameArea.x) || (myleft > myGameArea.x)) {
clicked = false;
}
return clicked;
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
}
function updateGameArea() {
myGameArea.clear();
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
if (myGameArea.x && myGameArea.y) {
if (myUpBtn.clicked()) {
myGamePiece.y -= 1;
}
if (myDownBtn.clicked()) {
myGamePiece.y += 1;
}
if (myLeftBtn.clicked()) {
myGamePiece.x += -1;
}
if (myRightBtn.clicked()) {
myGamePiece.x += 1;
}
}
myGamePiece.speedX = 0;
myGamePiece.speedY = 0;
if (myGameArea.key && (myGameArea.key == 37 || myGameArea.key == 65)) {
myGamePiece.speedX = -1;
}
if (myGameArea.key && (myGameArea.key == 39 || myGameArea.key == 68)) {
myGamePiece.speedX = 1;
}
if (myGameArea.key && (myGameArea.key == 38 || myGameArea.key == 87)) {
myGamePiece.speedY = -1;
}
if (myGameArea.key && (myGameArea.key == 40 || myGameArea.key == 83)) {
myGamePiece.speedY = 1;
}
myGamePiece.newPos();
myUpBtn.update();
myDownBtn.update();
myLeftBtn.update();
myRightBtn.update();
myGamePiece.update();
}
</script>
</body>
But I can't figure out how to make this background loop in canvas based on x and y position and how to make it change when you move.
I'm trying to learn about canvas myself, so I've been browsing through these questions. I thought yours would be a fun exercise to try.
Basically, I'm creating an object, and moving it at each iteration. I will constantly check the x position of my object. And depending on its value, I can change the background image.
Try this and see for yourself. Try moving your right arrow key and then left arrow key. You will notice the background image changes.
var canvas = document.getElementById("my-canvas");
var ctx = canvas.getContext("2d");
canvas.style.backgroundImage = "url('http://cdn.wonderfulengineering.com/wp-content/uploads/2014/07/background-wallpapers-26.jpg')";
function hero(x, y) {
this.x = x;
this.y = y;
this.moveLeft = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.x -= 5;
drawHero(this.x, this.y);
};
this.moveRight = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.x += 5;
drawHero(this.x, this.y);
};
this.moveUp = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.y -= 5;
drawHero(this.x, this.y);
}
this.moveDown = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.y += 5;
drawHero(this.x, this.y);
}
}
function drawHero(x,y) {
ctx.fillStyle = "red";
ctx.fillRect(x, y, 10, 10);
}
var hero1 = new hero(40, 40);
ctx.fillStyle = "red";
ctx.fillRect(40, 40, 10, 10);
window.addEventListener("keydown", function(event) {
if (event.keyCode == 38) {
hero1.moveUp();
}
else if (event.keyCode == 37) {
hero1.moveLeft();
}
else if (event.keyCode == 39) {
hero1.moveRight();
}
else {
hero1.moveDown();
}
});
setInterval(function() {
if (hero1.x <= 100) {
canvas.style.backgroundImage = "url('http://cdn.wonderfulengineering.com/wp-content/uploads/2014/07/background-wallpapers-26.jpg')";
}
else if (hero1.x > 100 && hero1.x <= 200) {
canvas.style.backgroundImage = "url('https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcRi2F1v1PXpOEYScFCbvmsV-74C573z8tFBvIPXwDO8d1KImpJ09Q')";
}
else {
canvas.style.backgroundImage = "url('https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcSOSNoN1aLzWvpwrENvqPb4tKgzfeeqlMsUeC0fjdGABXXLdLIo')";
}
},50);
#my-canvas {
border: 1px solid black;
}
<canvas id="my-canvas" width="400" height="400"></canvas>