Need Javascript Collision Detection in App Lab - javascript

I am making a game in the code.org App Lab. The game is based around Player 2 dropping meteors that Player 1 has to dodge. However, I have no idea how to do collision detection. can someone please help? I need a basic collision detection system to lower Player 1's health when a meteor hits them. Feel free to use the x and y values of Player 1, as well as add your own variables. I will give a shout-out to the person who help me. Here is my code:
var x = 104;
var y = 172;
var p1HP = 100;
var meteorCount = 25;
var mousex;
var mousey;
var meteorNum = 0;
//Code below triggers a screen change and music when a button is pressed.
onEvent("startButton", "click", function() {
setScreen("playscreen");
playSound("Brobot-Battle-(8-BIT)---Super-Paper-Mario-(192--kbps).mp3", false);
});
//Code below is basic movement for player.
onEvent("playscreen", "keydown", function(event) {
if (event.key=="w") {
getP1Pos();
setPosition("image2", x, y-8, 100, 100);
} else if (event.key=="a") {
getP1Pos();
setPosition("image2", x-8, y, 100, 100);
} else if (event.key=="d") {
getP1Pos();
setPosition("image2", x+8, y, 100, 100);
} else if (event.key=="s") {
getP1Pos();
setPosition("image2", x, y+8, 100, 100);
}
});
function getP1Pos() {
x = getXPosition("image2");
y = getYPosition("image2");
}
//code below resets the game when a retry button is pressed
onEvent("retry"||"retry2", "click", function( ) {
setScreen("startscreen");
p1HP = 100;
meteorCount = 20;
setText("p1HP", "P1 HP: "+p1HP);
setText("meteorCounter", "P2 METEORS: "+meteorCount);
});
//code below records mouse position
onEvent("playscreen", "mousemove", function(mouse) {
mousex = mouse.x;
mousey = mouse.y;
});
//code below makes the meteors go to the mouse and fall when the screen is clicked
onEvent("playscreen", "click", function() {
stopTimedLoop();
if (meteorNum==5) {
meteorNum = 1;
} else {
meteorNum = meteorNum+1;
}
meteorCount = meteorCount-1;
if (meteorCount==-1) {
setScreen("p1victory");
stopSound("Brobot-Battle-(8-BIT)---Super-Paper-Mario-(192--kbps).mp3");
} else {
setPosition("meteor"+meteorNum, mousex-20, mousey-20, 100, 100);
timedLoop(60, function() {
setPosition("meteor"+meteorNum, getXPosition("meteor"+meteorNum), getYPosition("meteor"+meteorNum) + 40, 100, 100);
});
setText("meteorCounter", "P2 METEORS: "+meteorCount);
}
});
//Insert collision detection algorithm here

I might have something that can work:
sprite.collide(target);
If it doesn't work, then please put the link for your code.org project.

Related

Tiled map overlap detection not working properly

I am building a tower defence game and I am facing an issue in Phaser with tiled maps.
You see different layers in tiled always have coordinates from (0,0) to (600,600) -> or whatever your tiled width and height is. I have a backgroundLayer and a path. The creeps properly collide with the path.
Now I am trying to change the cursor to a building sprite (for UI when I click on some button and select a tower I want it to turn red when it is on the road or above another tower/creep) and I am using an overlap function for path and buildings.
This overlap function in Phaser checks the rectangle of building sprite and path, but path rectangle is the whole map. The collision works but I only need an overlap. Any ideas how to achieve this? Here is my code.
var RedPlanetGame = RedPlanetGame || {};
var pressed = {
is: false
};
var buildingOverlaps = {
is: false
};
//title screen
RedPlanetGame.Game = function () {
};
RedPlanetGame.Game.prototype = {
create: function create() {
//A door for multyplayer
this.players = [];
this.player = new Player(1, 'Daniel', 300);
this.players.push(this.player);
this.playerInfo = {};
//Tile map
this.map = this.game.add.tilemap('sample2');
this.map.addTilesetImage('32x32_map_tile v3.1 [MARGINLESS]', 'gameTiles');
//background and layers
this.backgroundlayer = this.map.createLayer('backgroundLayer');
this.path = this.map.createLayer('path');
this.map.setCollisionBetween(1, 2000, true, 'backgroundLayer');
this.map.setCollisionBetween(1, 2000, true, 'path');
//objects from tile map
this.spawnCreepsAt = this.map.objects['objectsLayer'][0];
this.destinationForCreeps = this.map.objects['objectsLayer'][1];
//resize world
this.backgroundlayer.resizeWorld();
//this.game.world.setBounds(0, 0, 100, 100);
//groups
this.game.enemies = new UnitsPoolFactory(this.game);
this.game.buildings = this.game.add.group();//TODO: make buildings for each player
this.game.bullets = new BulletsPoolFactory(this.game);
//creep spawning
var _this = this;
const creepYOffset = 15;
setInterval(function () {
_this.game.enemies.factory(_this.spawnCreepsAt.x, _this.spawnCreepsAt.y + creepYOffset, UNIT_TYPES.CREEP1);
}, 1000);
//text and player info
var textX = 150;
var textY = 0;
this.playerInfo.gold = this.game.add.text(textX, textY, 'Player gold: ' + this.player.gold,
{font: "24px Arial", fill: '#FFD700'}
);
//Here is test straight forward code for building towers
this.game.build = this.game.add.group();
this.buildingSprite = this.game.add.sprite(0, 0, 'tower1-1');
this.game.physics.enable(this.buildingSprite, Phaser.Physics.ARCADE);
this.buildingSprite.anchor.setTo(0.5);
this.buildingSprite.scale.setTo(0.5);
this.game.build.add(this.buildingSprite);
console.log(this.path.getBounds());
console.log(this.backgroundlayer.getBounds());
},
update: function update() {
var _this = this;
//Camera follow cursor
if (this.game.input.mousePointer.x > gameHeight - gameHeight / 10) {
this.game.camera.x += 10;
} else if (this.game.input.mousePointer.x <= 100) {
this.game.camera.x -= 10;
}
if (this.game.input.mousePointer.y > gameWidth - gameWidth / 10) {
this.game.camera.y += 10;
} else if (this.game.input.mousePointer.y <= 100) {
this.game.camera.y -= 10;
}
//check for collision between enemy and non-path layer
this.game.physics.arcade.collide(this.game.enemies, this.backgroundlayer);
//checks for collision between bullets and enemies
this.game.physics.arcade.overlap(this.game.bullets, this.game.enemies, function (bullet, enemy) {
enemy.takeHit(bullet, _this.player);
bullet.kill();
}, null, this);
//updates enemies
this.game.enemies.forEach(function (enemy) {
enemy.onUpdate(_this.destinationForCreeps);
});
//updates buildings
this.game.buildings.forEach(function (building) {
building.onUpdate(_this.game.bullets);
});
//on mouse down event
if (this.game.input.activePointer.leftButton.isDown && !pressed.is) {//yo Yoda
//builds new building of type TOWER1
buffer(pressed, 1000);
if (Building.prototype.canBuild(this.player.gold, Tower1.prototype.moneyCost)) {
var poss = this.game.input.mousePointer;
BuildingsFactory(this.game, poss.x, poss.y, this.player, BUILDING_TYPES.TOWER1);
this.player.gold -= Tower1.prototype.moneyCost
} else {
alert('Not enought gold');
}
}
//Here is test straight forward code for building towers
if (Phaser.Rectangle.contains(this.buildingSprite.body, this.game.input.x, this.game.input.y)) {
this.buildingSprite.body.velocity.setTo(0, 0);
}
else {
this.game.physics.arcade.moveToPointer(this.buildingSprite, 700);
}
this.game.physics.arcade.collideGroupVsTilemapLayer(this.game.build, this.path, function (sprite) {
if (!buildingOverlaps.is) {
buffer(buildingOverlaps, 500);
console.log('overlap')
}
}, null, this, true);
},
render: function render() {
this.playerInfo.gold.text = 'Player gold: ' + this.player.gold;
}
};

Mouse position is only read on the first frame

i have been having trouble with reading a mouse position on a canvas. The code is working (semi) correctly as it reads the position when clicking he canvas in IE but only on one frame, in chrome it is just displaying the value as 0.
Here is the full code:
<script>
var blip = new Audio("blip.mp3");
blip.load();
var levelUp = new Audio("levelUp.mp3");
levelUp.load();
var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
context.font = '18pt Calibri';
context.fillStyle = 'white';
//load and draw background image
var bgReady = false;
var background = new Image();
background.src = 'images/background.jpg';
background.onload = function(){
bgReady = true;
}
var startMessage = 'Click the canvas to start';
//load plane image
var planeReady = false;
var planeImage = new Image();
planeImage.src = 'images/plane.png';
planeImage.onload = function() {
planeReady = true;
}
//load missile image
var missileReady = false;
var missileImage = new Image();
missileImage.src = 'images/missile-flipped.gif';
missileImage.onload = function() {
missileReady = true;
}
//initialise lives and score
var score = 0;
var lives = 3;
var missilesLaunched = 0;
var missileSpeed = 5;
var level = 1;
var missileX = 960;
var missileY = Math.random() * 500;
if (missileY > 480) {
missileY = 480;
}
function getMousePos(canvas, event) {
return {
x: input.x - rect.left,
y: input.y - rect.top
};
}
function update_images(event) {
var pos = getMousePos(canvas.getBoundingClientRect(), mouseInput);
planeImage.y = pos.y;
missileX = missileX - missileSpeed;
if (missileX < - 70) {
missilesLaunched++;
missileX = 960;
missileY = Math.random() * 500;
if (missileY > 480) {
missileY = 480;
}
blip.play();
score = missilesLaunched;
if (score % 5 == 0) {
missileSpeed = missileSpeed + 2;
level++;
levelUp.play();
}
}
}
function reload_images() {
if (bgReady = true) {
context.drawImage(background, 0, 0);
}
if (planeReady = true) {
context.drawImage(planeImage, 10, planeImage.y);
}
if (missileReady = true) {
context.drawImage(missileImage, missileX, missileY);
}
context.fillText('Lives: ' + lives, 200, 30);
context.fillText('Score: ' + score, 650, 30);
context.fillText('Level: ' + missileSpeed, 420, 30);
context.fillText('Position: ' + missileImage.y, 420, 70);
}
function main(event) {
var mouseInput = { x: 0, y: 0 };
document.addEventListener("mousemove", function (event) {
mouseInput.x = event.clientX;
mouseInput.y = event.clientY;
});
update_images(event);
reload_images();
if (lives > 0) {
window.requestAnimationFrame(main);
}
else {
}
}
function start() {
context.drawImage(background, 0, 0);
context.fillText('Click the canvas to start', 350, 250);
function startMain(event) {
game.removeEventListener("click", startMain);
main(event);
}
canvas.addEventListener("mousedown", startMain);
}
start();
</script>
Joe, you should actually be capturing the mouse position every time you click...
...but you're actually also starting a new game (without stopping the old one), every time you click, too.
First problem: starting game engine several times to draw on the same instance of the canvas
Solution:
In your start function, you need to remove the mousedown event listener, after you've triggered it.
function start () {
// ... other setup
function startMain (event) {
canvas.removeEventListener("click", startMain);
main(event);
}
canvas.addEventListener("click", startMain);
}
Now it will only listen for the first click, before starting, and will only start once.
Second Problem: mouse doesn't update as expected
Solution: two issues here...
...first, you are passing event into main on first call...
...after that, you're passing main into requestAnimationFrame.
requestAnimationFrame won't call it with an event, it will call it with the number of microseconds (or ms or some other unit as a fractional precision of ms) since the page was loaded.
So the first time you got main({ type: "mousedown", ... });.
The next time you get main(4378.002358007);
So lets refactor the startMain we had above, so that main never ever collects an event, just a time.
function startMain ( ) {
canvas.removeEventListener("click", startMain);
requestAnimationFrame(main);
}
The next problem is that even if you were getting just events, you're only ever capturing a click event (which as we mentioned earlier, fires a new copy of the game logic).
Your solution is to separate the code which catches mouse events from the code which reads mouse position.
var mouseInput = { x: 0, y: 0 };
document.addEventListener("mousemove", function (event) {
mouseInput.x = event.clientX;
mouseInput.y = event.clientY;
});
function getMousePos (rect, input) {
return {
x : input.x - rect.left,
y : input.y - rect.top
};
}
// currently in updateImages (should not be there, but... a different story)
var pos = getMousePos(canvas.getBoundingClientRect(), mouseInput);
You've got other problems, too...
You're calling getMousePos and passing in game at the moment. I don't see where game is defined in your JS, so either you're making game somewhere else (begging for bugs), or it's undefined, and your app blows up right there.
You should really be building this with your console / dev-tools open, in a hands-on fashion, and cleaning bugs in each section, as you go.

Set the maximum and current speed of a car in Phaser

I am making a top-down racing game using the Phaser framework which uses JS. I am having some trouble getting the car to slow down, at the moment it just stops when no button is pressed. I want it to slow down to stopped. Here is my code so far:
create: function () {
//run in canvas mode
this.game.renderer.clearBeforeRender - false;
this.game.renderer.roundPixels = true;
//Add arcade physics
this.game.physics.startSystem(Phaser.Physics.ARCADE);
//Add background sprites
this.game.add.sprite(0, 0, 'background');
this.game.add.sprite(0, 0, 'track');
//Add car sprite
car = this.game.add.sprite(800, 135, 'car-concept');
//Car physics settings
this.game.physics.enable(car, Phaser.Physics.ARCADE);
car.body.drag.set(100);
car.body.maxVelocity.set(200);
car.body.maxAngular = 500;
car.body.angularDrag = 500;
car.body.collideWorldBounds = true;
//Game input
cursors = this.game.input.keyboard.createCursorKeys();
this.game.input.keyboard.addKeyCapture([ Phaser.Keyboard.SPACEBAR]);
//pivot point
car.pivot.x = car.width * .3;
car.pivot.y = car.height * .5;
car.anchor.setTo(0.3, 0.5);
//scale the car
car.scale.setTo(0.3, 0.3);
},
update: function () {
car.body.velocity.x = 0;
car.body.velocity.y = 0;
car.body.angularVelocity = 0;
if(cursors.left.isDown)
{
car.body.angularVelocity = -200;
}
else if(cursors.right.isDown)
{
car.body.angularVelocity = 200;
}
if(cursors.up.isDown)
{
this.game.physics.arcade.velocityFromAngle(car.angle, -200, car.body.velocity)
if(this.currentSpeed < this.maxSpeed)
{
this.currentSpeed += 10;
}
}
else
{
if(this.currentSpeed > 0)
{
this.currentSpeed -= 10;
}
}
if(cursors.down.isDown)
{
this.game.physics.arcade.velocityFromAngle(car.angle, 200, car.body.velocity)
if(this.currentSpeed > 0)
{
this.currentSpeed -= 30;
}
}
},
speed: function()
{
this.maxSpeed = 100;
this.currentSpeed = 0;
},
I have looked a few questions on here about the same problem and this is how I got to the point where I am now. I have set the maxSpeed and currentSpeed but for some reason it won't allow me to actually use it. The console in the browser does not give me any errors, so if anyone can guide me on this, that would be great!
Thanks.
The reason it stops dead is because you're moving it with velocity, not acceleration - and are setting velocity to zero in your update loop (this effectively says "stop, now!").
Remove those lines and in your call to velocityFromAngle you should feed that into body.acceleration instead of body.velocity.
Here is an update loop you can use, although you'll need to mix in your currentSpeed settings and such like:
function update() {
if (cursors.up.isDown)
{
game.physics.arcade.accelerationFromRotation(sprite.rotation, 200, sprite.body.acceleration);
}
else
{
sprite.body.acceleration.set(0);
}
if (cursors.left.isDown)
{
sprite.body.angularVelocity = -300;
}
else if (cursors.right.isDown)
{
sprite.body.angularVelocity = 300;
}
else
{
sprite.body.angularVelocity = 0;
}
}
you never used currentSpeed. You set your speed to -200 and 200 in velocityFromAngle.

Clicakble planets

Im trying to make planets that give an alert message when clicked.
Problem is, onmousedown only works on canvas, as far I tested.
Code for planets:
var planets = [];
for (var b=0;b<3;b++) {
planets.push(planet(0,360,Math.random()*600,Math.random()*600));
}
function planet(I,shiips,xpos,ypos){
I = I||{};
I.ships = shiips;
I.x=xpos;
I.y=ypos;
return I;
}
code for click detection; tests both for planet object and the image
update = function(){
planetImage.onmousedown=function(){alert("works!")};
planets[0].onmousedown=function(){alert("works!")};
}
setInterval(update,100);
Im using canvas to draw the images, if that hhelps.
I found the following code that gives mouse position, but it doesnt work for me:
(function() {
var mousePos;
window.onmousemove = handleMouseMove;
setInterval(getMousePosition, 100); // setInterval repeats every X ms
function handleMouseMove(event) {
event = event || window.event; // IE-ism
mousePos = {
x: event.clientX,
y: event.clientY
};
}
function getMousePosition() {
var pos = mousePos;
if (!pos) {
// We haven't seen any movement yet
}
else {
// Use pos.x and pox.y
}
}
})();
Im trying to keep it simple, I don't really like jquery or anything complicated.
Once again: the problem is onmousedown only works on the canvas object, i.e.
canvas.onmousedown=function(){alert("works!")};
I got it working now with this code:
update = function(){
canvas.onmousedown=function(){
var e = window.event;
var posX = e.clientX;
var posY = e.clientY;
alert("X position: "+ posX + " Y position: " + posY);
};
setInterval(update,100);

Rotate a Roulette Wheel with the Mouse

I'm looking at this example (jsfiddle). It's almost what I need, but I need the user to "grab" the roulette with the mouse, then spin it, like you would do with a real one with your hand.
Like, you click and hold on the wheel, it "sticks" to your mouse, then you move your mouse to left or right, and release the button, and the wheel starts to spin until it stops.
Another question is, even if the user is doing that, can I choose a predetermined order to the wheel stops?
This is the jsFiddle:
$(function(){
var overWheel = false;
var mouseDown = false;
var lastMousePos = 0;
$('.wheel').on('mouseover', function(){
overWheel = true;
}).on('mouseout', function(){
overWheel = false;
});
$(document).on('mousedown', function(e){
if(overWheel){
lastMousePos = e.offsetY;
mouseDown = true;
}
}).on('mouseup', function(){
mouseDown = false;
});
$(document).on('mousemove', function(e){
if(overWheel && mouseDown){
handleWheel(e);
}
});
function handleWheel(e) {
var yPos = e.offsetY;
var direction = 0;
var deg = getRotationDegrees($('.wheel'));
if(yPos < lastMousePos){ // mouse is going up, move against the clock
console.log(yPos);
direction = -2;
} else { //mouse is going down, move with the clock
direction = 2;
}
$('.wheel').css({'-webkit-transform': 'rotate(' + (deg + (direction)) + 'deg)'});
}
function getRotationDegrees(obj){
var matrix = obj.css("-webkit-transform");
if(matrix !== 'none') {
var values = matrix.split('(')[1].split(')')[0].split(',');
var a = values[0];
var b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180/Math.PI));
} else { var angle = 0; }
return angle;
}
});​
I've managed to work.
I Used the jQuery Rotate library.
Thanks!

Categories

Resources