Javascript Making Enemy chase User - javascript

I'm trying to make a simple 2-d board game but I'm having trouble understanding how to make an enemy character move around and chase the player, I currently have a number of divs (for player, enemy, etc)
and the following code which moves the enemy div around the screen randomly
window.onload = function() {
var max_width = window.innerWidth;
var max_height = window.innerHeight;
var directions = {left:1,up:2,right:3,down:4}
var direction = getRandomDirection();
var distance = getRandomDistance();
var target = document.getElementById("robot");
var target_pos = {top:30, left:0}
var i = 0;
var render_rate = 24;
var move_step = 2;
setInterval(function(){
i++;
if(i > distance){
distance = getRandomDistance();
direction = getRandomDirection();
i = 0;
}
move(target,direction,move_step)
},render_rate)
function getRandomDistance(){
return Math.floor((Math.random() * 20) + 1) + 5;
}
function getRandomDirection(){
return Math.floor((Math.random() * 4) +1);
}
function move(el,driection,step){
switch(direction){
case directions.left: {
if(target_pos.left < max_width){
target_pos.left += step;
target.style.left = target_pos.left + "px";
}
break;
}
case directions.up: {
if(target_pos.top < max_height){
target_pos.top += step;
target.style.top = target_pos.top + "px";
}
break;
}
case directions.right: {
if(target_pos.left > 0){
target_pos.left -= step;
target.style.left = target_pos.left + "px";
}
break;
}
case directions.down: {
if(target_pos.top > 0){
target_pos.top -= step;
target.style.top = target_pos.top + "px";
}
break;
}
}
}
}
Can I edit this so that the enemy chases the player? (kind of like the ghosts in pacman) then implement a collision detection function to deal with the player when the enemy hits it?
I'm quite new to javascript but my understanding would be I would need to change:
function getRandomDistance(){
return Math.floor((Math.random() * 20) + 1) + 5;
}
to something along the lines of Math.floor(enemy.x - player.x);
or am I way off?
Many Thanks!

Related

How to collide using OOP JavaScript?

I am making a game(shooting game) using OOP javascript for my project. I already moved(player) and make the enemy disappear at the edge of the container. Now, I want to collide with the shooter(player) and enemy and display the message "Game Over". Here is my code of enemy.js and shooter.js. Also, my container.js.
container.js
class Container{
constructor(){
this.containerElement = document.getElementsByClassName("container")[0];
}
initialization(){
this.shooterElement = document.getElementsByClassName("shooter")[0];
let containerElement = document.getElementsByClassName("container")[0];
this.backgroundElement = document.getElementsByClassName("background")[0];
this.background = new Background(this.backgroundElement);
this.shooter = new Shooter(this.shooterElement);
document.addEventListener('keydown', (e)=>this.shooter.buttonGotPressed(e));
let enemyElement = document.getElementsByClassName("enemy")[0];
this.enemies = [];
setInterval(function(){
var top = Math.floor(Math.random() * 50) + 1;
var left = Math.floor(Math.random() * 550) + 1;
this.enemy = new Enemy({parentElement: containerElement, leftPosition: left, topPosition: top});
},400)
this.enemies.push(this.enemy);
}
}
let container = new Container();
container.initialization();
enemy.js
class Enemy{
constructor({parentElement,leftPosition, topPosition }){
let enemyElement = document.createElement("div");
this.enemyElement = enemyElement;
this.leftPosition = leftPosition;
this.topPosition = topPosition;
this.containerHeight = 600;
this.y = 15;
this.height = 40;
this.width = 50;
this.enemyElement.style.left = this.leftPosition + 'px';
this.enemyElement.style.top= this.topPosition + 'px';
this.enemyElement.style.height = this.height + 'px';
this.enemyElement.style.width = this.width + 'px';
this.enemyElement.style.position = "absolute";
this.enemyElement.style.background="url(images/enemy3.png)";
console.log(enemyElement)
parentElement.appendChild(this.enemyElement);
this.containerCollision = this.containerCollision.bind(this);
setInterval(this.containerCollision, 100);
}
containerCollision(){
if(this.topPosition >= this.containerHeight - this.width ){
this.enemyElement.style.display="none";
}
this.topPosition = this.topPosition + this.y;
this.enemyElement.style.top = this.topPosition + 'px';
}
}
shooter.js (this is the player)
class Shooter {
constructor(shooterElement){
this.shooterElement = shooterElement;
this.shooterleftPosition = 300;
this.shootertopPosition = 555;
this.containerWidth = 600;
this.width = 30;
this.height = 40;
this.x = 5;
this.y = 1;
this.shooterElement.style.left = this.shooterleftPosition + 'px';
this.shooterElement.style.top = this.shootertopPosition + 'px';
this.buttonGotPressed = this.buttonGotPressed.bind(this);
}
buttonGotPressed(e){
console.log(e);
if(e.key == "ArrowLeft"){
console.log(e.key);
if(this.shooterleftPosition <= 0){
this.shooterleftPosition = 0;
}
else
{
this.shooterleftPosition = this.shooterleftPosition - this.x;
}
console.log(this.shooterleftPosition)
this.shooterElement.style.left = this.shooterleftPosition +'px';
}
if(e.key == "ArrowRight"){
this.shooterleftPosition = this.shooterleftPosition + this.x;
this.shooterElement.style.left = this.shooterleftPosition +'px';
if(this.shooterleftPosition >= this.containerWidth - this.width){
this.shooterleftPosition = this.containerWidth - this.width;
this.shooterElement.style.left = this.leftPosition + 'px';
}
}
}
}
Now, How do I detect and collide shooter(player) and enemy and display the message/alert "Game Over". If the enemy touches the shooter(player). Here is pic too.
How do i know enemy touched the player and display game over in this pic
What I tried to detect the collision of player and enemy
collidingShooter(){
if (this.enemies.push(this.enemy)>1)
{
(
([this.enemies][this.enemy].top <= this.shootertopPosition + 50) &&
([this.enemies][this.enemy].top >= this.shootertopPosition) &&
([this.enemies][this.enemy].left >= this.shooterleftPosition) &&
([this.enemies][this.enemy].left <= this.shooterleftPosition+ 50)
)
console.log("hitttt");
this.enemies.splice(this.enemy,1);
// this.shooterElement.splice(1);
}
}
I believe that you messed something up here
First of all you use array in the wrong way:
[this.enemies][this.enemy].top
What it does:
Creates new array with one element (which is this.enemies array), now it converts this.enemy to a string = 'object Object' and tries to find a key in this new array, which propably returns undefined and now it tries to get top of undefined.
What you probably wanted to do is:
this.enemies[this.enemies.indexOf(this.enemy)].top
But even though it has no oop sense.
What I would do:
function checkCollision() {
for (let i = 0; i < this.enemies.length; i++) {
if (areColliding(this.shooter, this.enemies[i])) {
console.log('hit')
}
}
}
function areColliding(o1, o2) {
if (o1.top <= o2.top + o2.height &&
o1.top >= o2.top &&
o1.left <= o2.left + o2.width &&
o1.left >= o2.left) {
return true
}
return false
}
There are better collision algorithms than aabb and even if you want to do this in this way, your game can get very slow if you have thousands of enemies. There is algorithm to split game world in to smaller rectangles and check for collision inside them.

How to move div randomly on load of the page using javascript [closed]

I would like to know how I can move a div in a random direction on load of the webpage using java script.
I'am looking for something like how the enemies/ghosts move randomly in the pacman game.
how can this be achieved?
Here you go:
window.onload = function(){
var max_width = window.innerWidth;
var max_height = window.innerHeight;
var directions = {left:1,up:2,right:3,down:4}
var direction = getRandomDirection();
var distance = getRandomDistance();
var target = document.getElementById("ghost");
var target_pos = {top:0,left:0}
var i = 0;
var render_rate = 40;
var move_step = 2;
setInterval(function(){
i++;
if(i > distance){
distance = getRandomDistance();
direction = getRandomDirection();
i = 0;
}
move(target,direction,move_step)
},render_rate)
function getRandomDistance(){
return Math.floor((Math.random() * 20) + 1) + 5;
}
function getRandomDirection(){
return Math.floor((Math.random() * 4) + 1);
}
function move(el,direction,step){
switch(direction){
case directions.left: {
if(target_pos.left < max_width){
target_pos.left += step;
target.style.left = target_pos.left + "px";
}
break;
}
case directions.up: {
if(target_pos.top < max_height){
target_pos.top += step;
target.style.top = target_pos.top + "px";
}
break;
}
case directions.right: {
if(target_pos.left > 0){
target_pos.left -= step;
target.style.left = target_pos.left + "px";
}
break;
}
case directions.down: {
if(target_pos.top > 0){
target_pos.top -= step;
target.style.top = target_pos.top + "px";
}
break;
}
}
}
}
#ghost{
background-color:#def;
height:40px;
width:40px;
position:absolute;
left:0;
top:0;
}
<div id="ghost"></div>

When rotating a character, it rotates a certain amount, and then goes back

I'm just starting to throw together a simple game where your a dot that need food, or else you die. Simple, it's just a fun thing to do.
I'm trying a different method than what I normally do, where the character rotates and then moves.
When the character rotates, it goes a certain amount, and then rotates in the other direction a certain amount. Then it repeats. How do I make it just rotate one direction, rather than alternating(and sort of just going in the same general direction the whole time).
Rotate script:
self.rotationy = 0;
self.rotationx = 0;
self.turnLeft = function() {
self.rotationy -= 0.1;
};
self.turnRight = function() {
self.rotationy += 0.1;
};
self.move = function() {
var posX = Math.sin(self.rotationy);
var posZ = Math.cos(self.rotationy);
self.locationx += posX + 3;
self.locationy += posZ + 3;
};
If it's important, here's the update script:
self.update = function() {
self.hunger -= 0.003;
self.updateColour();
if (self.hunger <= 0) {
self.die();
} else if (self.hunger >= 1) {
self.die();
}
if (self.locationx <= 20) {
self.locationx = canvas.width - 21;
} else if (self.locationx >= canvas.width - 20) {
self.locationx = 21;
} else if (self.locationy <= 20) {
self.locationy = canvas.height - 21;
} else if (self.locationy >= canvas.height) {
self.locationy = 21;
}
drawCircle(ctx, self.locationx, self.locationy, 20, self.colour);
};
self.die = function() {
};
setInterval(self.update, 50);
};
Here's a JSFiddle: http://jsfiddle.net/hzhubf8o/
Also note that I haven't created a function to clear the path that's taken.
Thanks in advance!
Thanks to Siguza, I have the answer(posting it here in case anyone had a similar problem)
I was adding +3, which caused the character to go along the positive. It was supposed to make him go faster, which instead was supposed to be * 3(also suggested by him).
self.locationx += posX + 3;
self.locationy += posZ + 3;
Changes to:
self.locationx += posX * 3;
self.locationy += posZ * 3;

Need help programming my Raycasting engine in html5

Hello I am trying to code a raycasting engine in html5, based off of this tutorial, http://www.permadi.com/tutorial/raycast/index.html
I am having problems going about the loop used to find walls. Someone please help!
var player = {
posX:65,
posY:65,
dir:45,
}
var canvas = document.getElementById('hud');
var ctx = canvas.getContext('2d');
var texture = new Image();
texture.src = 'tilesFpsRpg.png';
texture.onload = rayTrace;
var worldMap = [[1,1,1,1,1,1,1,1,1,1],
[1,0,1,0,1,0,0,0,0,1],
[1,0,1,0,1,0,0,1,0,1],
[1,0,1,0,1,1,1,1,0,1],
[1,0,0,0,0,1,0,1,0,1],
[1,0,0,0,0,0,0,1,0,1],
[1,0,0,1,0,1,0,1,0,1],
[1,0,0,1,1,1,1,1,0,1],
[1,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1]];
function rayTrace () {
for(var i = 0; i < 320; i++){
var currentRayDir = player.dir - 30;
if (currentRayDir < 0) {
currentRayDir = currentRayDir + 360;
} else if (currentRayDir >= 360) {
currentRayDir = currentRayDir - 360;
} else {
currentRayDir = currentRayDir;
}
console.log(currentRayDir);
if (180 >= currentRayDir >= 0) {
var horY = Math.floor((Math.floor(player.posY/64) * (64) - 1)/64);
var hya=-64;
} else {
var horY = Math.floor((Math.floor(player.posY/64) * (64) + 64)/64);
var hya=64;
}
console.log(horY);
if (90 >= currentRayDir >= 270) {
var verX = Math.floor((Math.floor(player.posX/64) * (64) + 64)/64);
var vxa = 64;
} else {
var verX = Math.floor((Math.floor(player.posX/64) * (64) - 1)/64);
var vxa = -64;
}
console.log(verX);
var horX = player.posX + (player.posY-horY)/Math.tan(currentRayDir);
var hxa = 64/Math.tan(currentRayDir);
var verY = player.posY + (player.posX-verX)*Math.tan(currentRayDir);
var vya = 64 * Math.tan(currentRayDir);
while (worldMap[horX][horY] == 0 || worldMap[verX][verY] == 0) {
var hit; // 1 means that a vertical wall was hit and 0 means a horizontal wall was hit
if (worldMap[horX][horY] > 0) {
hit = 0;
break;
}
if (worldMap[verX][verY] > 0) {
hit = 1;
break;
}
horX=Math.floor((horX+hxa) / 64);
horY=Math.floor((horY+hya) / 64);
verX=Math.floor((verX+vxa) / 64);
verY=Math.floor((verY+vya) / 64);
}
if (hit = 0) {
var distance = Math.sqrt((player.posX - horX)(player.posX - horX) + (player.posY - horY)(player.posY - horY));
var undistortedDistance = distance * Math.cos(player.dir - currentRayDir);
var sliceheight = 64 / undistortedDistance * 277;
drawImage(texture,horX % 64,0,1,64,i,(100 - sliceheight/2),1,sliceheight);
} else {
var distance = Math.sqrt((player.posX - verX)(player.posX - verX) + (player.posY - verY)(player.posY - verY));
var undistortedDistance = distance * Math.cos(player.dir - currentRayDir);
var sliceheight = Math.ceil(64 / undistortedDistance * 277);
drawImage(texture,verX % 64,0,1,64,i,(100 - sliceheight/2),1,sliceheight);
}
}
}
rayTrace ();
I run into problems with the while loop. What the loop is trying to do is check the worldMap array to see if the ray that is currently being casted hits a wall and if not, move onto the next intersection to see if a wall is hit and so on. I'm thinking that there is probably a better way to do this than the while loop.

Javascript Collision Issues

I have a ball bouncing around the screen and I need to write code that essentially ends the game when it collides with the player... This is my current code, but it isn't working. Let me know if you need more information.
if(playerLoc == ballLoc){
gameOver();
}
Where playerLoc/ballLoc are measured based of X and Y axis measurements.
<script language="JavaScript">
//get info, process data, update screen objects
//instance vars
var player;
var ball;
var score;
var axis;
var ballaxis;
//initial speeds
var dx = 6;
var dy = 6;
var currentScore = 0;
var timer;
//set initial conditions for ball and paddle
var playerTop = 400;
var playerLeft = 200;
var ballLeft = 228;
var ballTop = 4;
var playerLoc = playerLeft + playerTop;
var ballLoc = ballLeft + ballTop;
function init(){
//instantiate HTML object instance vars
player = document.getElementById('player');
ball = document.getElementById('ball');
score = document.getElementById('score');
axis = document.getElementById('axis');
ballaxis = document.getElementById('ballaxis');
//register key listener with document object
document.onkeydown = keyListener;
//start the game loop
start();
}
function keyListener(e){
if(!e){
//for IE
e = window.event;
}
if(e.keyCode==37 && playerLeft > 0){
//keyCode 37 is left arrow
playerLeft -= 10;
player.style.left = playerLeft + 'px';
}
if(e.keyCode==39 && playerLeft < 450){
//keyCode 39 is right arrow
playerLeft += 10;
player.style.left = playerLeft + 'px';
}
if(e.keyCode==38 && playerTop > 0){
//keyCode 38 is up arrow
playerTop -= 10;
player.style.top = playerTop + 'px';
}
if(e.keyCode==40 && playerTop < 450){
//keyCode 40 is down arrow
playerTop += 10;
player.style.top = playerTop + 'px';
}
}
function start(){
//game loop
render();
detectCollisions();
difficulty();
axisMeasure();
//end conditions
if(playerLoc == ballLoc){
gameOver();
}
else{
//still in play - keep the loop going
timer = setTimeout('start()',50);
}
}
function detectCollisions(){
//just reflect the ball on a collision
//a more robust engine could change trajectory of ball based
//on where the ball hits the paddle
if(collisionX())
dx = dx * -1;
if(collisionY())
dy = dy * -1;
}
function collisionX(){
//check left and right boundaries
if(ballLeft < 2 || ballLeft > 480)
return true;
else {
return false;
}
}
function collisionY(){
//check if at top of playing area
if(ballTop < 2 || ballTop > 480)
return true;
else {
return false;
}
}
function render(){
moveBall();
updateScore();
}
function moveBall(){
ballLeft += dx;
ballTop += dy;
ball.style.left = ballLeft;
ball.style.top = ballTop;
}
function axisMeasure(){
axis.innerHTML = 'P X-Axis: ' + playerLeft + ' P Y-Axis: ' + playerTop
ballaxis.innerHTML = 'B X-Axis: ' + ballLeft + ' B Y-Axis: ' + ballTop
}
function updateScore(){
currentScore += 5;
score.innerHTML = 'Score: ' + currentScore;
}
function difficulty(){
//as the game progresses, increase magnitude of the vertical speed
if(currentScore % 1000 == 0){
if(dy > 0)
dy += 1;
else
dy -= 1;
}
}
function gameOver(){
//end the game by clearing the timer, modifying the score label
clearTimeout(timer);
score.innerHTML += " Game Over";
score.style.backgroundColor = 'rgb(128,0,0)';
Lol.. well you have like no code shown. So this is a complete shot in the dark.
if(playerLoc.x == ballLoc.x && playerLoc.y == ballLoc.y){
gameOver();
}
OR, even try the distance method.
var distance = Math.sqrt((ballLoc.x- playerLoc.x) *(ballLoc.x-playerLoc.x) + (ballLoc.y - playerLoc.y) * (ballLoc.y-playerLoc.y));
if(distance < *some amount*)}
gameOver();
}
Also heres a live demo of the distance check in action.
Edit
Ok well now that the code is posted, my answer is somewhat irrelevant, but Ill keep it here regardless since the distance check is a valid method that would even work in the OP's case.
var ballX = ballLeft + (ballWidth/2),
ballY = ballTop + (ballHeight/2),
playerX = playerLeft + (playerWidth/2),
playerY = playerTop + (playerHeight/2);
var distance = Math.sqrt((ballX - playerX) *(ballX - playerX) + (ballY - playerTop) * (ballY - playerTop ));
if(distance < 25){ gameOver(); }

Resources