<html>
<head>
<!--
by Michal Budzynski
http://michalbe.blogspot.com
http://twitter.com/michalbe
-->
<title>Simple game with HTML5 Canvas part 4</title>
<style>
body {
margin:0px;
padding:0px;
text-align:center;
}
canvas{
outline:0;
border:1px solid #000;
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body>
<canvas id='c'></canvas>
<script src="game.js"></script>
</body>
</html>
var width = 320,
height = 500,
gLoop,
c = document.getElementById('c'),
ctx = c.getContext('2d');
c.width = width;
c.height = height;
var clear = function(){
ctx.fillStyle = '#d0e7f9';
ctx.clearRect(0, 0, width, height);
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.closePath();
ctx.fill();
};
var howManyCircles = 10, circles = [];
for (var i = 0; i < howManyCircles; i++)
circles.push([Math.random() * width, Math.random() * height, Math.random() * 100, Math.random() / 2]);
var DrawCircles = function(){
for (var i = 0; i < howManyCircles; i++) {
ctx.fillStyle = 'rgba(255, 255, 255, ' + circles[i][3] + ')';
ctx.beginPath();
ctx.arc(circles[i][0], circles[i][1], circles[i][2], 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
}
};
var MoveCircles = function(e){
for (var i = 0; i < howManyCircles; i++) {
if (circles[i][1] - circles[i][2] > height) {
circles[i][0] = Math.random() * width;
circles[i][2] = Math.random() * 100;
circles[i][1] = 0 - circles[i][2];
circles[i][3] = Math.random() / 2;
}
else {
circles[i][1] += e;
}
}
};
var player = (function(){
var that = this;
that.image = new Image();
that.image.src = "angel.png";
that.width = 65;
that.height = 95;
that.frames = 1;
that.actualFrame = 0;
that.X = 0;
that.Y = 0;
that.isJumping = false;
that.isFalling = false;
that.jumpSpeed = 0;
that.fallSpeed = 0;
that.jump = function() {
if (!that.isJumping && !that.isFalling) {
that.fallSpeed = 0;
that.isJumping = true;
that.jumpSpeed = 17;
}
};
that.checkJump = function() {
that.setPosition(that.X, that.Y - that.jumpSpeed);
that.jumpSpeed--;
if (that.jumpSpeed === 0) {
that.isJumping = false;
that.isFalling = true;
that.fallSpeed = 1;
}
};
that.fallStop = function(){
that.isFalling = false;
that.fallSpeed = 0;
that.jump();
};
that.checkFall = function(){
if (that.Y < height - that.height) {
that.setPosition(that.X, that.Y + that.fallSpeed);
that.fallSpeed++;
} else {
that.fallStop();
}
};
that.moveLeft = function(){
if (that.X > 0) {
that.setPosition(that.X - 5, that.Y);
}
};
that.moveRight = function(){
if (that.X + that.width < width) {
that.setPosition(that.X + 5, that.Y);
}
};
that.setPosition = function(x, y){
that.X = x;
that.Y = y;
};
that.interval = 0;
that.draw = function(){
try {
ctx.drawImage(that.image, 0, that.height * that.actualFrame, that.width, that.height, that.X, that.Y, that.width, that.height);
}
catch (e) {
}
if (that.interval == 4 ) {
if (that.actualFrame == that.frames) {
that.actualFrame = 0;
}
else {
that.actualFrame++;
}
that.interval = 0;
}
that.interval++;
};
})();
player.setPosition(~~((width-player.width)/2), height - player.height);
player.jump();
document.onmousemove = function(e){
if (player.X + c.offsetLeft > e.pageX) {
player.moveLeft();
} else if (player.X + c.offsetLeft < e.pageX) {
player.moveRight();
}
};
/*
* part 4 - platforms & collisions
*/
var nrOfPlatforms = 7,
platforms = [],
platformWidth = 70,
platformHeight = 20;
var Platform = function(x, y, type){
var that=this;
that.firstColor = '#FF8C00';
that.secondColor = '#EEEE00';
that.onCollide = function(){
player.fallStop();
};
if (type === 1) {
that.firstColor = '#AADD00';
that.secondColor = '#698B22';
that.onCollide = function(){
player.fallStop();
player.jumpSpeed = 50;
};
}
that.x = ~~ x;
that.y = y;
that.type = type;
that.draw = function(){
ctx.fillStyle = 'rgba(255, 255, 255, 1)';
var gradient = ctx.createRadialGradient(that.x + (platformWidth/2), that.y + (platformHeight/2), 5, that.x + (platformWidth/2), that.y + (platformHeight/2), 45);
gradient.addColorStop(0, that.firstColor);
gradient.addColorStop(1, that.secondColor);
ctx.fillStyle = gradient;
ctx.fillRect(that.x, that.y, platformWidth, platformHeight);
};
return that;
};
var generatePlatforms = function(){
var position = 0, type;
for (var i = 0; i < nrOfPlatforms; i++) {
type = ~~(Math.random()*5);
if (type === 0)
type = 1;
else
type = 0;
platforms[i] = new Platform(Math.random() * (width - platformWidth), position, type);
if (position < height - platformHeight)
position += ~~(height / nrOfPlatforms);
}
}();
var checkCollision = function(){
platforms.forEach(function(e, ind){
if (
(player.isFalling) &&
(player.X < e.x + platformWidth) &&
(player.X + player.width > e.x) &&
(player.Y + player.height > e.y) &&
(player.Y + player.height < e.y + platformHeight)
) {
e.onCollide();
}
});
};
/*
* part 4 end
*/
var GameLoop = function(){
clear();
MoveCircles(5);
DrawCircles();
if (player.isJumping) player.checkJump();
if (player.isFalling) player.checkFall();
/*
* part 4
*/
platforms.forEach(function(platform){
platform.draw();
});
checkCollision();
/*
* end part4
*/
player.draw();
gLoop = setTimeout(GameLoop, 1000 / 50);
};
GameLoop();
Output
This bin was created anonymously and its free preview time has expired (learn why). — Get a free unrestricted account
Dismiss xKeyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |