Part 1 - Introduction & Background
Part 2 - Character & Animation
Part 3 - Physics & Controls
Part 4 - Platforms & Collisions
Part 5 - Scrolling & Game States
Part 4a. DRAWING THE PLATFORMS
There are two types of platforms our character is able to jump on - ordinary one (orange) and green one - trampoline, gives extra speer and hyper-ultra-high jump. There are always seven platforms on the screen at the time (I tried different number, from 4 to 10 and only 7 works fine with screen size I declare at the beginning). Let's create Platform "class" (function platforms will inherit from).
var Platform = function(x, y, type){ //function takes position and platform type var that=this; that.firstColor = '#FF8C00'; that.secondColor = '#EEEE00'; that.onCollide = function(){ player.fallStop(); }; //if platform type is different than 1, set right color & collision function (in this case just call player's fallStop() method we defined last time if (type === 1) { //but if type is equal '1', set different color and set jumpSpeed to 50. After such an operation checkJump() method will takes substituted '50' instead of default '17' we set in jump(). that.firstColor = '#AADD00'; that.secondColor = '#698B22'; that.onCollide = function(){ player.fallStop(); player.jumpSpeed = 50; }; } that.x = ~~x; that.y = y; that.type = type; return that; };Now it's necessary to create function which will generate all that platform stuff and put it into platforms[] array we will define shortly. After that it will be nice to draw the platforms on the screen.
var nrOfPlatforms = 7, platforms = [], platformWidth = 70, platformHeight = 20; //global (so far) variables are not the best place for storing platform size information, but in case it will be needed to calculate collisions I put it here, not as a Platform attributes var generatePlatforms = function(){ var position = 0, type; //'position' is Y of the platform, to place it in quite similar intervals it starts from 0 for (var i = 0; i < nrOfPlatforms; i++) { type = ~~(Math.random()*5); if (type == 0) type = 1; else type = 0; //it's 5 times more possible to get 'ordinary' platform than 'super' one platforms[i] = new Platform(Math.random()*(width-platformWidth),position,type); //random X position if (position < height - platformHeight) position += ~~(height / nrOfPlatforms); } //and Y position interval }(); //we call that function only once, before game startExtending Platform object with draw() method:
var Platform = function(x, y, type){ (...) that.draw = function(){ ctx.fillStyle = 'rgba(255, 255, 255, 1)'; //it's important to change transparency to '1' before drawing the platforms, in other case they acquire last set transparency in Google Chrome Browser, and because circles in background are semi-transparent it's good idea to fix it. I forgot about that in my 10kApart entry, I think because Firefox and Safari change it by default 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); //drawing gradient inside rectangular platform }; return that; };Platform must be drawn on each frame, so updating GameLoop() is a must.
var GameLoop = function(){ (...) platforms.forEach(function(platform){ platform.draw(); }); (...) };Part 4b. COLLISIONS Nice, but there is no interaction between angel and the platforms. But one little function will handle everything. Let me introduce checkCollision():
var checkCollision = function(){ platforms.forEach(function(e, ind){ //check every plaftorm if ( (player.isFalling) && //only when player is falling (player.X < e.x + platformWidth) && (player.X + player.width > e.x) && (player.Y + player.height > e.y) && (player.Y + player.height < e.y + platformHeight) //and is directly over the platform ) { e.onCollide(); } }) }Another update of main loop (it is good moment to comment line with MoveCircles() function - if platforms are standing still why background is falling down? It will makes more sense when we will implement platform scrolling. Whole GameLoop() function should looks like that now:
var GameLoop = function(){ clear(); //MoveCircles(5); DrawCircles(); if (player.isJumping) player.checkJump(); if (player.isFalling) player.checkFall(); platforms.forEach(function(platform){ platform.draw(); }); checkCollision(); player.draw(); gLoop = setTimeout(GameLoop, 1000 / 50); }Final result: [platforms & collisions demo] Source: [MichalBe Github] I think next part will be the last one, but who knows:).
Tutorial: Simple game with HTML5 Canvas
Part 1 - Introduction & Background
Part 2 - Character & Animation
Part 3 - Physics & Controls
Part 4 - Platforms & Collisions
Part 5 - Scrolling & Game States
Thanks, following your tutorial it took me only an hour to create this http://pdfcv.com/game :)
ReplyDeleteExcellent one, but you draw() method you write here is different than in your full .js file. It's missing something :)
ReplyDeletegreat tutorial Michal, i will create a new game with similar gameplay base on this, and I'll try to do in a good object-oriented way.
ReplyDeleteGreetings
how can i place images instead of gradient colors for the plattforms? i tried with im.src but i always get errors no matter what i do :(
ReplyDeleteuse the same way in which you draw the player - ctx.drawImage().
ReplyDeleteIn your example although you call draw on the platforms, you never call generatePlatforms so they never appear?
ReplyDeleteI call it in line 20, one, just after defining it.
ReplyDeleteonce*
ReplyDeletei am working on a similar project. I am trying to move/draw the "player" with mouse click. Can you help me?
ReplyDeletei have question....what is the difference between the e.pageX versus e.x...i'm new to this 'event'.
ReplyDeleteHi,
ReplyDeleteIt really is a helpful piece of code but,
when I am using Linear Gradient for platforms, the platforms appear for sometime and then they disappear, I guess after 20-30 jumps.
var gradient = ctx.createLinearGradient(0, that.y, 0, that.y + platformHeight);
gradient.addColorStop(0, that.secondColor);
gradient.addColorStop(0.5, that.firstColor);
gradient.addColorStop(1, that.secondColor);
colorStops also works fine with Radial Gradient.
Please dont mind if I have code something wrong :)
really great tutorial. The procedure is very good explained. It helped me a lot to set up my template for some experiments for FB games. I'd like however to suggest a few optimizations that save the processor from performing unnecessary calculations:
ReplyDelete1st) add a "break" in the first collision detection inside the loop ( I've replaced the 'foreach' with for (i=...). It doesn't need to proceed in this case with the other platforms.
2nd) The collision condition itself is too expensive. It performs every time 5 (1+4) compare-operations, every one of them has an 'add' operation. There is a much more cheaper condition:
if ( player.isFalling &&
//only when player is falling
!(player.x + player.width < platforms[i].x ||
player.x > platforms[i].x + platformWidth ||
player.y + player.height < platforms[i].y ||
player.y > platforms[i].y + platformHeight )
where only the worst case needs all operations to be performed by the processors.
Please find more details about it in my post:
http://theodosis-gameprogramming.blogspot.gr/2011/07/collision-detection-by-detecting-no.html
Otherwise, it is a top tutorial. Thank you very much for sharing it with us.
Here reader can easily learn different functions of HTML5 game development.
ReplyDeleteGood and interesting article..
ReplyDeleteJavaScript Training
JavaScript Training in Chennai
javascript tutorial for beginners
Online JavaScript Training
18 inches weave hair
ReplyDelete16 inches weave hair
14 inches weave hair
12 inches weave hair
nice tutorial ,I totally love your website and find many of the posts to be just what I am interested in. Do you offer guest writers to post content material for you? I would not mind creating a piece of text regarding websites to watch movies or on a few of the things you’re posting about on this site. Great site!
ReplyDeleteweb and mobile app development company
Great blog . I really liked it thank you
ReplyDeleteThanks
Cpa offers
This comment has been removed by the author.
ReplyDeleteIt's an awesome blog to know about translation proofreading. I was searching for this type of article so that I can get so knowledge on translation proofreading. I am a professional gamer and for few days i am facing some issues with playing local games.
ReplyDelete
ReplyDeleteBEST WORLD NOOB GAMES OF 2022