I'm trying to develop game similar to snake games in old model phones. I created the game, which you can have a look at here. But when controlling the snake I switched the width and height of the snake to turn in any direction, but I want to make the snake to look like real snake, I mean it should have an L shape when turning and gradually changes into straight again, Please give me any idea, how I can do that using canvas. the snake is a fillrect() in canvas.
The following is the entire code..
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Snake</title>
</head>
<body>
Use Arrow keys of to control the snake.
<canvas id="can_game" height="400" width="400" style="border:1px solid;"></canvas>
<div id="score_div"></div>
<div id="time">0.00</div>
<script type="text/javascript">
var score=0,fps=30,canvas=document.getElementById("can_game"),context=canvas.getContext('2d'),dir="",score_div=document.getElementById("score_div"),width_h=45,pass='left',timediv=document.getElementById("time"),time=0.00;
var player = {
color : '#ff00',
px :'180',
py : '384',
height : '12',
width : '45',
draw : function(){
context.fillRect(this.px,this.py,this.width,this.height);
}
}
var ball = {
x :Math.round(Math.random(4)*400),
y : Math.round(Math.random(4)*400),
draw : function() {
context.beginPath();
context.fillStyle = "#ff0000";
context.arc(this.x,this.y,6,0,2*Math.PI,false);
context.fill();
}
}
setInterval(function(){
score_div.innerHTML=score;
timediv.innerHTML=Math.round(time/1000)+" Seconds";
time=parseInt(time)+1000/fps;
update();
draw();
var test=hitTestPoint(player.px,player.py,player.width,player.height,ball.x,ball.y);
if(test===true)
{
ball.x=Math.round(Math.random(80)*400);
ball.y=Math.round(Math.random(80)*400);
score+=10;
width_h+=3;
}
console.log(player.py,canvas.width);
if(player.px <=0)
player.px=360;
else if(player.px >= (canvas.width))
player.px=0;
else if(player.py <= 0)
player.py=360;
else if(player.py >= (canvas.height))
player.py=0;
document.onkeydown = function() {
var key_pressed = window.event.keyCode;
/* if(key_pressed == 32)
dir = "freeze";*/
if(key_pressed == 37)
dir = "left";
else if(key_pressed == 39)
dir = "right";
else if(key_pressed == 38)
dir = "up";
else if(key_pressed == 40)
dir = "down";
};
},1000/fps);
function hitTestPoint(x1, y1, w1, h1, x2, y2)
{
if ((x1 <= x2 && x1+w1 >= x2) &&
(y1 <= y2 && y1+h1 >= y2))
return true;
else
return false;
}
function draw()
{
context.clearRect(0,0,canvas.width,canvas.height);
player.draw();
ball.draw();
context.fill();
}
function update()
{
switch(dir){
case "left":
player.px-=3;
player.width=width_h;
player.height=12;
break;
case "right":
player.px= parseInt(player.px)+3;
player.width=width_h;
player.height=12;
break;
case "up":
player.py-=3;
player.width=12;
player.height=width_h;
break;
case "down":
player.py+=3;
player.width=12;
player.height=width_h;
break;
}
}
</script>
</body>
</html>
You might want to take a look at this CSS deck tutorial to solve your problem.
Here the trick is , that the snake is composed of individual small and discrete blocks rather than the one as in your case where its a static block, and every time the snake is progressed one step, one block is popped from the rear and a new block is added to the top(face).
So when the snakes moves in another direction(or axis) its face block are gradually added in another axis and it gives an illusion of snake turning in the way you expect it
Related
I have used p5.js library in order to make a small circle game.
in which when the user clicks outside the circle, the output is:
But even when I'm clicking inside the circle, still the output says that I've clicked outside the circle.
here is the index.html file's code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> A Simple Circle Game </title>
</head>
<body>
<p style="text-align: center"> A Simple Circle Game </b> </p>
<script src="https://cdn.jsdelivr.net/npm/p5#1.5.0/lib/p5.js"></script>
<script type="text/javascript" src="sketch.js"></script>
<script src="condition1.js"></script>
</body>
</html>
the sketch.js file is as follow:
function setup(){
createCanvas(500,200).center();
noStroke();
background(230);
circle(250,100,100);
}
function draw() {
// Draw a circle
fill(240, 204, 0);
circle(mouseX, mouseY, 5);
}
the condition1.js file is as follows:
function mousePressed() {
dist = Math.sqrt(250 * 250 + 100 * 100);
if (mouseX > 566 && mouseX < 666 && mouseY < 258 && mouseY > 158 ) {
document.write("You clicked the circle!");
} else {
document.write("You clicked outside the circle!");
}
}
In the above code, in the if condition, shall I use any other logic or is there any else issue due to which my game isn't behaving in the way it ought to be?
I tried changing the dimensions of mouseX and mouseY but all in vain. SSo, I'm expecting a better approach towards my solution.
Your condition1.js file should look like this. I used the p5.Vector for the circle position, but you can change it if you want. To be clear, the squaring is skipped to make it a bit faster.
function mousePressed(event)
{
let distanceX = event.clientX - circlePos.x;
let distanceY = event.clientY - circlePos.y;
if (distanceX * distanceX + distanceY * distanceY < (circleRadius * circleRadius))
{
document.write("You clicked the circle!");
}
else
{
document.write("You clicked outside the circle!");
}
}
function mousePressed()
{
if(dist(mouseX,mouseY, Circle.x, Circle.y) <= Circle.Radius)
{
//DO THING HERE
}
}
P5.js has a built in distance function, it uses square root so its a little slow, but it gets the job done.
Im making a car parking project with Adobe Animate CC (HTML5).
I have into my canvas a Car and its Wheels.With the command below i can rotate the wheels left or right by pressing keyboard arrows.
document.onkeydown = keyHandler.bind(this);
function keyHandler(event) {
var e = event||window.event;
//left
if(e.keyCode == 37) {
this.car.wheels3.rotation-=2;
But i want to make it to rotate in a certain rotation ratio , like a real wheel of a car rotates.I think i have to make a method but i dont know how to use rotate property with the method i want to create.Any thought/ help appreciated.
You need wheel animation actually:
createjs.Tween.get(car.wheel,{loop:true,override:true}).to({rotation:"360"}, 1000);
//or
createjs.Tween.get(car.wheel,{loop:true,override:true}).to({rotation:"-360"}, 1000);
Update, based on new circumstances:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Example</title>
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script>
function init()
{
var stage = new createjs.Stage("canvas");
createjs.Ticker.setFPS(24); //set some FPS
createjs.Ticker.addEventListener("tick", stage); //set autiomatic refresh
//let's draw something like wheels, with registration point somewhere in the middle :)
var wheels=new createjs.Shape();
wheels.graphics.beginFill("#CCCCCC").drawRect(-100,0,20,50);
wheels.graphics.beginFill("#CCCCCC").drawRect(-100,15,200,20);
wheels.graphics.beginFill("#CCCCCC").drawRect(100,0,20,50);
stage.addChild(wheels);
wheels.x=200;
wheels.y=100;
document.addEventListener("keydown", onKeyDown );
var wheelsInitialRotation=wheels.rotation; //save whells initial rotation
var maximumAngleForRotation=20; //set maximum angle
function onKeyDown(e)
{
var amount;
e = e || window.event;
switch(e.keyCode)
{
//right
case 39:
amount=2;
break;
//left
case 37:
amount=-2;
break;
//all other
default:
amount=0;
}
//check is new angle is not more or less then allowed :)
if(!(wheels.rotation+amount>wheelsInitialRotation+maximumAngleForRotation || wheels.rotation+amount<wheelsInitialRotation-maximumAngleForRotation))
{
wheels.rotation+=amount;
}
}
}
</script>
</head>
<body onload="init();">
<canvas id="canvas" width="400" height="400"></canvas>
</body>
</html>
I am trying to create a rect that moves on keypress for a pong game and when I press the key the left rect disappears..
Any ideas how to fix the problem? It is really important..
The code is written in vanilla javascript so please don't write jQuery..
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pong</title>
<script type="text/javascript">
var x = 100;
var y = 100;
var xmoveFirst = 720;
var ymoveFirst = 0;
var xmoveSecond = 30 ;
var ymoveSecond = 0;
function canvas() {
var can = document.getElementById('theCanvas');
can.style.backgroundColor = "black";
var ctx = can.getContext('2d');
//first player
ctx.fillStyle="white";
ctx.fillRect(xmoveFirst,ymoveFirst,5,75);
//second player
ctx.fillStyle = 'white';
ctx.fillRect(xmoveSecond,ymoveSecond,5,75);
//first player move
function moveFirst(eFirst) {
ctx.clearRect(0,0,750,750); //clear rects
if (eFirst.keyCode == 40) {
ymoveFirst+=25;
console.log("first,"+ymoveFirst);
}
else if (eFirst.keyCode == 38) {
ymoveFirst-=25;
console.log("first,"+ymoveFirst);
}
ctx.fillStyle="white";
ctx.fillRect(xmoveFirst,ymoveFirst,5,75);
ctx.fillRect(xmoveSecond,ymoveSecond,5,75);
}
var first = document.onkeydown = moveFirst;
//second player move
function moveSecond(eSecond) {
ctx.clearRect(0,0,750,750);
if (eSecond.keyCode == 83) {
ymoveSecond+=25;
console.log("second,"+ymoveSecond);
}
else if (eSecond.keyCode == 87) {
ymoveSecond-=25;
}
ctx.fillStyle="white";
ctx.fillRect(xmoveFirst,ymoveFirst,5,75);
ctx.fillRect(xmoveSecond,ymoveSecond,5,75);
console.log("second,"+ymoveSecond)
}
var second = document.onkeydown = moveSecond;
}
83,87
</script>
</head>
<body onload="canvas()">
<canvas id="theCanvas" width="750" height="750"></canvas>
</body>
</html>
This line: can.width=can.width; resets the canvas width.
When you change the canvas size (width or height), you clear the canvas (making everything black). After this line, you are only redrawing the rightmost paddle, so the left one remains missing.
You'll need to redraw the leftmost paddle as well if you want it to come back. Here is the modified moveRight() function:
function moveRight(eFirst) {
if (eFirst.keyCode==40) {
ymoveFirst+=25;
console.log(ymoveFirst);
}
else if (eFirst.keyCode==38) {
ymoveFirst-=25;
console.log(ymoveFirst);
}
can.width=can.width;
ctx.fillStyle="white";
// Redraw BOTH paddles
ctx.fillRect(xmoveFirst,ymoveFirst,5,75);
ctx.fillRect(xmoveSecond,ymoveSecond,5,75);
}
Also, replace
document.onkeydown = moveFirst; and document.onkeydown = moveSecond;
with
document.addEventListener("keydown", moveFirst);, and document.addEventListener("keydown", moveSecond);
Currently, you are overwritting the first listener with document.onkeydown = moveSecond;. By using addEventListener, you don't overwrite the ones that already exist.
As the title suggests, I am having trouble with object collision...
I am currently working on a 2d Html5 canvas game using JavaScript. I know how to keep the "player" object from going outside the width/height of the game canvas, and i know how to do something when the player collides with an object (such as a power up or enemy or whatever) but i just don't know how to make a "solid" object meaning when the player hits the solid object, the player just stops, and cannot go through the solid object.
This is what I have now (not all the code just what I feel is relevant, sorry if it's too much/too little.:
var canvasPlayer = document.getElementById('canvasPlayer');
var ctxPlayer = canvasPlayer.getContext('2d');
var canvasWalls = document.getElementById('canvasWalls');
var ctxWalls = canvasWalls.getContext('2d');
function checkKeyDown(e) {
var keyID = (e.keyCode) || e.which;
if (keyID === 38 || keyID === 87) { // up arrow OR W key
if (!player1.isDownKey && !player1.isLeftKey && !player1.isRightKey) {
player1.isUpKey = true;
e.preventDefault();
} }
if (keyID === 39 || keyID === 68) { //right arrow OR D key
if (!player1.isDownKey && !player1.isLeftKey && !player1.isUpKey) {
player1.isRightKey = true;
e.preventDefault();
} }
if (keyID === 40 || keyID === 83) {//down arrow OR S key
if (!player1.isUpKey && !player1.isLeftKey && !player1.isRightKey) {
player1.isDownKey = true;
e.preventDefault();
} }
if (keyID === 37 || keyID === 65) {//left arrow OR A key
if (!player1.isDownKey && !player1.isUpKey && !player1.isRightKey) {
player1.isLeftKey = true;
e.preventDefault();
}
}
}
Walls.prototype.draw = function (){
ctxWalls.drawImage(imgSprite,this.srcX,this.srcY,this.width,this.height,this.drawX,this.drawY,this.width,this.height);
this.checkHitPlayer();
};
Walls.prototype.checkHitPlayer = function() {
if (this.drawX > player1.drawX &&
this.drawX <= player1.drawX + player1.width &&
this.drawY >= player1.drawY &&
this.drawY < player1.drawY + player1.height) {
player1.isUpKey = false;
player1.isDownKey = false;
player1.isRightKey = false;
player1.isLeftKey = false;
}
};
This works... except when trying to go up or left, the player only moves maybe 2-3 pixels, so it takes 3 left or up arrows to go left or up. As well the player can move straight through the wall which is not what i want. Any help is much appreciated sorry if i included too much or not enough code. Oh, i also forgot to mention the game is a puzzle game, and I have it set-up so a player can only move one direction at a time until hitting a wall.
If you just want your player to stop when the reach a wall, you can apply some math:
For example: assume your player is a 10px by 10px rectangle and the right wall's X position is 200.
The X position of the right side of the rectangle is calculated like this:
var playerRightSide = player.x + player.width;
You can test if the player has reached the wall like this:
if( playerRightSide >= 200 )
If the user tries to push their player beyond the wall, you would hold the player to the left of the wall using the players X position.
if( playerRightSide >= 200 ) { player.x = 190; }
The 190 is the wall's X position (200) minus the player's width (10).
Read further if you're interested in doing more advanced collision testing.
Many basic game collisions can be classified into 3 types:
Circle versus Circle collision
Rectangle versus Rectangle collision
Rectangle versus Circle collision
Here’s an illustration of how to detect each of these common collisions.
Assume you define a circle like this:
var circle1={
x:30,
y:30,
r:10
};
Assume you define a rectangle like this:
var rect1={
x:20,
y:100,
w:20,
h:20
};
You can detect Circle vs Circle collisions like this...
...Using this Circle vs Circle collision-test code:
// return true if the 2 circles are colliding
// c1 and c2 are circles as defined above
function CirclesColliding(c1,c2){
var dx=c2.x-c1.x;
var dy=c2.y-c1.y;
var rSum=c1.r+c2.r;
return(dx*dx+dy*dy<=rSum*rSum);
}
You can detect Rectangle vs Rectangle collisions like this...
...Using this Rectangle vs Rectangle collision-test code:
// return true if the 2 rectangles are colliding
// r1 and r2 are rectangles as defined above
function RectsColliding(r1,r2){
return !(r1.x>r2.x+r2.w || r1.x+r1.w<r2.x || r1.y>r2.y+r2.h || r1.y+r1.h<r2.y);
}
You can detect Rectangle vs Circle collisions like this...
...Using this Rectangle vs Circle collision-test code:
// return true if the rectangle and circle are colliding
// rect and circle are a rectangle and a circle as defined above
function RectCircleColliding(rect,circle){
var dx=Math.abs(circle.x-(rect.x+rect.w/2));
var dy=Math.abs(circle.y-(rect.y+rect.y/2));
if( dx > circle.r+rect.w2 ){ return(false); }
if( dy > circle.r+rect.h2 ){ return(false); }
if( dx <= rect.w ){ return(true); }
if( dy <= rect.h ){ return(true); }
var dx=dx-rect.w;
var dy=dy-rect.h
return(dx*dx+dy*dy<=circle.r*circle.r);
}
For example, you can use these collision tests to respond to a player touching a power-up cube:
// create a circular player object
// that's located at [30,30] and has a radius of 10px
var player={x:30,y:30,r:10};
// create a rectangular power-up at position [200,30]
var powerup={x:200, y:30, w:20, h:20};
// Let's say the user keys the player to coordinate [200,35]
// (touching the power-up)
player.x = 220;
player.y = 35;
// you can test if the circular player is touching the rectangular power-up
if( RectCircleColliding(powerup,player) ) {
// the player has collided with the power-up, give bonus power!
player.power += 100;
}
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/u6t48/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:20px; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
ctx.fillStyle="lightgray";
ctx.strokeStyle="skyblue";
// top collision circle vs circle
var circle1={x:30,y:30,r:10};
var circle2={x:70,y:40,r:10};
var circle3={x:100,y:30,r:10};
var direction1=1;
// middle collision rect vs rect
var rect1={x:20,y:100,w:20,h:20};
var rect2={x:50,y:110,w:20,h:20};
var rect3={x:90,y:100,w:20,h:20};
var direction2=1;
// bottom collision rect vs circle
var circle4={x:30,y:200,r:10};
var rect4={x:50,y:205,w:20,h:20};
var circle5={x:100,y:200,r:10};
var direction3=1;
function drawAll(){
ctx.clearRect(0,0,canvas.width,canvas.height);
drawCircle(circle1);
drawCircle(circle2);
drawCircle(circle3);
drawCircle(circle4);
drawCircle(circle5);
drawRect(rect1);
drawRect(rect2);
drawRect(rect3);
drawRect(rect4);
}
function drawCircle(c){
ctx.beginPath();
ctx.arc(c.x,c.y,c.r,0,Math.PI*2,false);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
function drawRect(r){
ctx.beginPath();
ctx.rect(r.x,r.y,r.w,r.h);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
// return true if the 2 circles are colliding
function CirclesColliding(c1,c2){
var dx=c2.x-c1.x;
var dy=c2.y-c1.y;
var rSum=c1.r+c2.r;
return(dx*dx+dy*dy<=rSum*rSum);
}
// return true if the 2 rectangles are colliding
function RectsColliding(r1,r2){
return !(r1.x>r2.x+r2.w || r1.x+r1.w<r2.x || r1.y>r2.y+r2.h || r1.y+r1.h<r2.y);
}
// return true if the rectangle and circle are colliding
function RectCircleColliding(rect,circle){
var dx=Math.abs(circle.x-(rect.x+rect.w/2));
var dy=Math.abs(circle.y-(rect.y+rect.h/2));
if( dx > circle.r+rect.w/2 ){ return(false); }
if( dy > circle.r+rect.h/2 ){ return(false); }
if( dx <= rect.w ){ return(true); }
if( dy <= rect.h ){ return(true); }
var dx=dx-rect.w;
var dy=dy-rect.h
return(dx*dx+dy*dy<=circle.r*circle.r);
}
var fps = 15;
function animate() {
setTimeout(function() {
requestAnimFrame(animate);
// circle vs circle
circle2.x = circle2.x+direction1;
if( CirclesColliding(circle2,circle1) || CirclesColliding(circle2,circle3) ){
direction1=-direction1;
}
// rect vs rect
rect2.x = rect2.x+direction2;
if( RectsColliding(rect2,rect1) || RectsColliding(rect2,rect3) ){
direction2=-direction2;
}
// rect vs circle
rect4.x = rect4.x+direction3;
if( RectCircleColliding(rect4,circle4) || RectCircleColliding(rect4,circle5) ){
direction3=-direction3;
}
drawAll();
}, 1000 / fps);
}
animate();
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
I'm fairly new to Javascript and using a canvas in general and I cant get collision detection to work with my canvas walls.
I normally have a small square painted on the canvas that I can control with the arrow keys on the keyboard but it would continue past the canvas.
This is the working code without my attempts of collision detection.
<!DOCTYPE html>
<html>
<head>
<canvas id = "gameCanvas" width="400" height="400" style = "border:1px solid #000000;"></canvas>
<style type="text/css"></style>
</head>
<body>
<script type="text/javascript">
var c = document.getElementById("gameCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "rgb(255, 0, 0)";
var snake = {
x: 5
, y: 5
};
function drawSnake() {
ctx.clearRect(0,0, ctx.canvas.width, ctx.canvas.height);
ctx.fillRect(snake.x ,snake.y,20,20);
}
window.addEventListener("keydown", function(event) {
if (event.keyCode == 39)
snake.x += 5;
else if (event.keyCode == 37)
snake.x -= 5;
else if (event.keyCode == 38)
snake.y -= 5;
else if (event.keyCode == 40)
snake.y += 5;
drawSnake();
});
drawSnake();
</script>
</body>
</html>
This is my attempt at collision detection.
//Wall Collision
if(snake.x >= canvas.w || snake.x <= -1 || snake.y >= canvas.h || snake.y <= -1) {
return;
}
Entering this code leaves me with a blank canvas and I don't understand why.
I want the square to reset its position once it collides with the canvas wall and that's where I'm having all the trouble.
You shouldn't put it under addEventListener. Then, the return is ending the JS script.
You want to put your collision detection code in (the beginning of) drawSnake().
See this working example.
There are also a few other things wrong with your code that I feel that I should address (all changed in the example).
<canvas> should be in the <body> element, not the <head>
canvas is not defined in JS (you can remove it from ctx.canvas.width
change canvas.w and canvas.h to ctx.width and ctx.height in the collision detection code
instead of returning from the drawSnake() function, reset the snake to its default coordinates
draw a better snake