HTML5 physical game development and html5 Game Development
Since the last chapter was released to the present day, it has passed April, so you can't help but wait for a long time ~ It is not that I don't pay attention to my blog, but that it takes less time to write more blogs. When I got free today, I looked back at my previous articles and found that I hadn't written any articles for four months. Then I had to say "Bitter ~", I am afraid that this series of articles will take longer, so I can make a pen immediately or leave a breeze for this series of articles.
First, let's review the content in the previous two articles:
HTML5 physical game development-cross-country Mountain bicycles (2) create a controllable bicycle
Http://blog.csdn.net/yorhomwang/article/details/21300253
HTML5 physical game development-cross-country Mountain bicycles (I) Build a wide range of Terrain
Http://blog.csdn.net/yorhomwang/article/details/19710537
What we want to achieve today is: when the key part of our bicycle hits the wall, it will immediately smash it. In other words, it will be "Broken Bicycles ". OK. Let's get started ~
Put two images first:
※Again, The lufylegend. js open-source html5 game engine and box2dweb physical engine are used in this development. Please download and use them on the official website. The official website address has been mentioned in Chapter 1.
I. Crushing Principle
Anyone who has used hammers knows how to break a bicycle (if you have never used it and you don't know how to use it, I suggest you ask Raytheon sol? If you don't, let me teach you three tips:
Method 1: attach a hammer.
Method 2: Go to Asja to find Raytheon's eldest brother. This is the fastest speed. It is estimated that your bicycle will have only one atom left before you finish smoking a cigarette.
Method 3: replace a hammer with a screw driver or other tools somewhere, and unload your bicycle parts together.
Obviously, these three methods have their own advantages. However, since our bicycles are combined in one place, we have to split them one by one, I chose 3 (in fact, Box2dWeb does not have a hammer and does not recognize Raytheon ). We mentioned in the previous chapter how to combine parts by using the joints in Box2dWeb. These joints link parts together. If these joints are destroyed, then these parts will be scattered. But how to destroy the joints? In b2World of Box2dWeb, there is a DestroyJoint function. The parameter is the b2Joint object to be destroyed. Let's see how to destroy the joints in lufylegend.
First, the b2Joint object created through the LBox2d key joint function in lufylegend will be returned, that is:
var j = LStage.box2d.setRevoluteJoint(a.box2dBody, b.box2dBody);LStage.box2d.world.DestroyJoint(j);
We can save the rotary joint created by calling setRevoluteJoint in the variable j, and then directly call the LStage. box2d. world. DestroyJoint function when the destroy function is executed. The parameter is j.
What if we have multiple joints? Put it in the array. you must be smart. You have thought of this before I say this.
Let's get started with the code.
Ii. Update the bicycle class and Main class
In the previous chapter, we focused on how to implement the bicycle category. This time, because we want to smash it, we need to first operate on it and put a few bombs. Make preparations before loading the bomb, so that you do not need to blow yourself over. Therefore, you must first create a box to hold the place where the bomb is to be blown up. It happened that the Main class was passing by (for details about Main, refer to chapter 1). I handed it over and sang, saying, "How do you install two things for me now ?", The Main class thinks: "This role can take charge of all the programs. In case of such a fire, it is not a good thing to delete me by using a delete operation .", So he took this responsibility for me helplessly. But what are the two things do you want to know? It turns out to be an array named jointList and a bool variable called gameOverController. These two containers hold all the generated joints in one pipe, and whether the game is over or not. The Main constructor is transformed as follows:
Function Main () {var s = this; base (s, LSprite, []);/** set the scene size */s. sceneWidth = 8500; s. sceneHeight = LStage. height + 1000;/** joint list */s. jointList = new Array ();/** game end controller */s. gameOverController = false ;}
I am sorry for the obvious style of the above section. I have read more about "Water Margin" recently. I hope you can include it.
We know that a bomb must have a firewire or a more advanced switch. It is a device to detonate it. Let's leave this work to Main. Modify the init method of Main:
Main. prototype. init = function () {var s = this;/** Add Borders */s. addBorder ();/** add to pavement */s. addRoad ();/** add to Bike */s. addBicycle ();/** Add a rigid body collision event */LStage. box2d. setEvent (LEvent. POST_SOLVE, s. postSolve);/** add loop events */s. addEventListener (LEvent. ENTER_FRAME, s. loop );};
It mainly adds a call to the LStage. box2d. setEvent function. This function is a method of the LBox2d class (LStage. box2d is the instantiated object of LBox2d). The specific usage is as follows:
■ SetEvent (type, func)
Parameter introduction:
Collision event types in the type box2d world
Function scheduled when the func triggers an event
The collision event type can be:
LEvent. BEGIN_CONTACT: this function is triggered at the beginning of the collision.
LEvent. END_CONTACT: this function is triggered when the collision ends.
LEvent. POST_SOLVE: this function will be processed after the collision
LEvent. PRE_SOLVE: When the collision is about to begin before the collision
Here we chose POST_SOLVE, that is, the function will be processed after the collision. In fact, other event types should be selected, and the effect should be the same. When an event is triggered, the scheduling function is postSolve. You can leave this function to Main ~ [Main class: it is recommended to install two (T_T)]
Main. prototype. postSolve = function (contact) {if (world. gameOverController) return; var l = world. jointList; if (l. length = 0) return; // obtain the collision LSprite object var cA = contact. getFixtureA (). getBody (). getUserData (); var cB = contact. getFixtureB (). getBody (). getUserData (); // determine whether to destroy a bicycle if (// ---------------------------------------------- // condition 1: When a bicycle and a wall collide // lift (cA. name = "wall" & cB. na Me = "bicycle") | (cA. name = "bicycle" & cB. name = "wall") | // ------------------------------------------------ // condition 2: when a bicycle handlebar, handlebar to a wheel bracket, or seat encounters another object // ---------------------------------------------- (cA. trigger = "destroy_bicycle" & cB. name! = "Bicycle") | (cA. name! = "Bicycle" & cB. trigger = "destroy_bicycle") {// remove all joints on the bicycle to destroy the bicycle. for (var I in l) {var jo = l [I]; // remove the joint LStage. box2d. world. destroyJoint (jo); // set the game end controller to end world. gameOverController = true;} // remove all joints from the bicycle joint list. length = 0; // Add the game end prompt var gameOverText = new LTextField (); gameOverText. text = "Game Over"; gameOverText. size = 50; gameOverText. alpha = 0; gameOverText. x = (LStage. width-gameOverText.getWidth () * 0.5; gameOverText. y = (LStage. height-gameOverText.getHeight () * 0.5; addChild (gameOverText); LTweenLite. to (gameOverText, 5, {delay: 1.5, alpha: 1 });}};
This function will accept a parameter. What object is a parameter? Actually, I don't know. Actually, there are GetFixtureA and GetFixtureB functions. The two functions can get the rigid shape of the colliding rigid body, get the b2Body object through the rigid GetBody, and then use the GetUserData of the b2Body to get the final LSprite object.
After introducing the parameters, let me introduce the execution logic of this function. First, if the game has ended or the jointList is empty, the subsequent code is no longer run. If the code continues to run, the LSprite of the two colliding rigid bodies is first obtained, then, judge the game end. If it passes through, execute the game end code. What is the world? If you start from chapter 1, you should understand it. PostSolve is a callback function, and this in it does not point to Main.
In the 19-row-long judgment condition, I set two conditions to meet one of the two conditions and destroy the joints: Condition 1: When the bicycle and the wall collide; condition 2: when a bicycle's handlebar, handlebar to a wheel bracket, or seat hits another object.
The code for destroying parts is mainly worth noting that in box2d, The DestroyJoint function is used to destroy joints, which has been mentioned in the "Crushing principle, this function is in the b2World class, and the world attribute of LBox2d is the instantiated object of b2World.
The key to ending the game is to see the name and trigger of the LSprite object of the collision b2Body. Where are these attributes set? Of course, it is in the Bicycle class. Next, let's take a look at the code added and improved in the Bicycle class.
First, let's take a look at the changes to the init function of Bicycle:
Bicycle. prototype. init = function () {var s = this; var sx = s. sx; var sy = s. sy;/** wheel radius */var wheelR = 20;/** distance between wheels */var gapBetweenWheelAndWheel = 100; /** distance from the handle to the wheel */var gapBetweenWheelAndHandlebar = 50;/** handle size */var handlebarWidth = 20, handlebarHeight = 5; /** distance from the seat to the wheel bracket */var gapBetweenWheelFrameAndSeat = 30;/** seat size */var seatWidth = 30, seatHeight = 5; /** bracket size */var frameSize = 10;/** add bracket * // bracket var frameAObj = new LSprite (); frameAObj on the wheel. x = sx + gapBetweenWheelAndWheel/2; frameAObj. y = sy + frameSize/2; frameAObj. addBodyPolygon (gapBetweenWheelAndWheel, frameSize, 1, 5); world. addChild (frameAObj); s. bodyList. push (frameAObj); // the carriage to the wheel var frameBObj = new LSprite (); frameBObj. trigger = "destroy_bicycle"; frameBObj. x = sx + gapBetweenWheelAndWheel-frameSize/2; frameBObj. y = sy-gapBetweenWheelAndHandlebar/2; frameBObj. addBodyPolygon (frameSize, gapBetweenWheelAndHandlebar, 1, 2); world. addChild (frameBObj); s. bodyList. push (frameBObj);/** add handlebars */var handlebarObj = new LSprite (); handlebarObj. trigger = "destroy_bicycle"; handlebarObj. x = sx + gapBetweenWheelAndWheel-handlebarWidth/2-frameSize; handlebarObj. y = sy-gapBetweenWheelAndHandlebar + handlebarHeight/2; handlebarObj. addBodyPolygon (handlebarWidth, handlebarHeight, 1 ,. 5); world. addChild (handlebarObj); s. bodyList. push (handlebarObj);/** add seat * // The bracket from the seat to the wheel bracket var seatFrameObj = new LSprite (); seatFrameObj. x = sx + 30; seatFrameObj. y = sy-gapBetweenWheelFrameAndSeat/2; seatFrameObj. addBodyPolygon (frameSize, gapBetweenWheelFrameAndSeat, 1, 1); world. addChild (seatFrameObj); s. bodyList. push (seatFrameObj); // seat var seatObj = new LSprite (); seatObj. trigger = "destroy_bicycle"; seatObj. x = sx + 30; seatObj. y = sy-gapBetweenWheelFrameAndSeat-seatHeight/2; seatObj. addBodyPolygon (seatWidth, seatHeight, 1 ,. 5); world. addChild (seatObj); s. bodyList. push (seatObj);/** add wheel * // Avar wheelobj = new LSprite (); wheelobj on the left. x = sx-wheelR; maid. y = sy; maid. addBodyCircle (wheelR, wheelR, wheel R, 1, 2.5 ,. 2 ,. 4); world. addChild (maid); s. bodyList. push (maid); // The Right wheel Bvar wheelBObj = new LSprite (); wheelBObj. x = sx + gapBetweenWheelAndWheel-wheelR; wheelBObj. y = sy; wheelBObj. addBodyCircle (wheelR, wheelR, wheel R, 1, 2.5 ,. 2 ,. 4); world. addChild (wheelBObj); s. bodyList. push (wheelBObj);/** add joint * // rotary joint world of wheel A and wheel bracket. jointList. push (LStage. box2d. setRevoluteJoint (frameAObj. box2dBody, fig. box2dBody); // rotary joint world of wheel B and wheel bracket. jointList. push (LStage. box2d. setRevoluteJoint (frameAObj. box2dBody, wheelBObj. box2dBody); // The welding joint of the handlebar to the wheel bracket and the wheel bracket world. jointList. push (LStage. box2d. setWeldJoint (frameAObj. box2dBody, frameBObj. box2dBody); // the frame of the handlebar to the wheel and the welding joint of the handlebar world. jointList. push (LStage. box2d. setWeldJoint (handlebarObj. box2dBody, frameBObj. box2dBody); // the frame of the wheel and the welding joint of the seat world. jointList. push (LStage. box2d. setWeldJoint (seatFrameObj. box2dBody, frameAObj. box2dBody); // The bracket of the seat and the welding joint of the seat world. jointList. push (LStage. box2d. setWeldJoint (seatFrameObj. box2dBody, seatObj. box2dBody);/** traverse all bicycle parts rigid body */for (var key in s. bodyList) {var obj = s. bodyList [key]; // Add the mouse and drag if (obj. box2dBody) obj. setBodyMouseJoint (true); // sets the object name obj. name = "bicycle";}/** set the primary rigid body */s. mainBody = frameAObj. box2dBody;/** set the rigid body for the drag/drop operation */s. tcBody = wheelBObj. box2dBody ;};
The main change is here:
/** Add joint * // The rotary joint world of wheel A and wheel bracket. jointList. push (LStage. box2d. setRevoluteJoint (frameAObj. box2dBody, fig. box2dBody); // rotary joint world of wheel B and wheel bracket. jointList. push (LStage. box2d. setRevoluteJoint (frameAObj. box2dBody, wheelBObj. box2dBody); // The welding joint of the handlebar to the wheel bracket and the wheel bracket world. jointList. push (LStage. box2d. setWeldJoint (frameAObj. box2dBody, frameBObj. box2dBody); // the frame of the handlebar to the wheel and the welding joint of the handlebar world. jointList. push (LStage. box2d. setWeldJoint (handlebarObj. box2dBody, frameBObj. box2dBody); // the frame of the wheel and the welding joint of the seat world. jointList. push (LStage. box2d. setWeldJoint (seatFrameObj. box2dBody, frameAObj. box2dBody); // The bracket of the seat and the welding joint of the seat world. jointList. push (LStage. box2d. setWeldJoint (seatFrameObj. box2dBody, seatObj. box2dBody ));
I added all the joints to jointList of wolrd, so that we can traverse and retrieve the joints and destroy them, this has been implemented in the postSolve of Main.
Another change is: 1. Add a name attribute to all rigid bodies belonging to the bicycle and set it to "bicycle"; 2, add the trigger attribute to the rigid body of the key part (the handlebar, the bracket to the wheel, and the seat) and set it to "destroy_bicycle", indicating that if these parts encounter other rigid bodies not belonging to the bicycle, the game ends.
As for the Rigid Body with name "wall", there is actually only one (bottomBorder bottom border, prompting the bicycle to end the game when it falls to the bottom ):
Main. prototype. addBorder = function () {var s = this;/** create a border * // set the border size var borderSize = 10; // The top border var topBorder = new LSprite (); topBorder. x = s. sceneWidth/2; topBorder. y = 5; topBorder. addBodyPolygon (s. sceneWidth, borderSize, 0); s. addChild (topBorder); // right border var rightBorder = new LSprite (); rightBorder. x = s. sceneWidth-5; rightBorder. y = s. sceneHeight/2; rightBorder. addBodyPolygon (borderSize, s. sceneHeight, 0); s. addChild (rightBorder); // Bottom Border var bottomBorder = new LSprite (); bottomBorder. name = "wall"; bottomBorder. x = s. sceneWidth/2; bottomBorder. y = s. sceneHeight-5; bottomBorder. addBodyPolygon (s. sceneWidth, borderSize, 0); s. addChild (bottomBorder); // left border var leftBorder = new LSprite (); leftBorder. x = 5; leftBorder. y = s. sceneHeight/2; leftBorder. addBodyPolygon (borderSize, s. sceneHeight, 0); s. addChild (leftBorder );};
OK. Run the code to obtain the effect shown in the image at the top of this article.
Source code: http://files.cnblogs.com/yorhom/box2dBicycle%283%29.rar
Test address: http://game.hdc.h5stars.com/201428053f36b0853f15 ~
This series of tutorials is here to address. In fact, if you want to make a real "cross-country Mountain Bike" game, you also need to map the rigid body and determine the victory. These are all very simple. You can do it yourself ~ (The demo I am currently working on should be used as a tool for venting. If the pressure is high, I will take this virtual bicycle and drop it down ~ Haha)
This chapter is here first. If there are any omissions in the article, please correct me. Of course, you are welcome to leave a message below this article. I will try my best to reply to you.
----------------------------------------------------------------
You are welcome to repost my article.
Reprinted Please note: