Quote:

Two days ago to see children playing plants vs zombies, come to think of it many years ago and often play this game, is the classic a leisure game, then wrote a whim is weekend, spent a lot of time to find the material and writing code, feeling on basic functionality is ready (to go to work, don’t have enough time to make), write out look, really a little critical liver!

Effect:

Implementation approach

  1. Use two canvases to achieve, the first canvas to draw things that do not need to be updated, such as background, buttons, points, cards, etc.;
  2. The second canvas draws things that are frequently updated, such as zombies walking, zombies eating plants, zombies dying, plants swaying, pea shoots shooting peas, bullets moving, sunlight generation, sunlight collection, etc.
  3. The realization of animation, by image constantly switch, open up a total timing task 2, 100 milliseconds redraw canvas, of course, other each animation will reopen timed tasks (I call them the subtasks), they are not responsible for rendering, only responsible for changing the corresponding parameters, rendering is done by the addition of, such as the zombie walking animation: Start subtask 100 ms to perform a picture switch, switch to the last one, return to the first one, if you want to move around at the same time change the position of the picture, after the subtask modification is completed, the general task will be drawn naturally;
  4. The realization of the card, it is to write the two CARDS (sunflower, pea seedlings), give the card made of the same size square to control the mouse click event, when click on the card, will create the corresponding plants and follow the mouse, move the mouse to the appropriate location and then click the corresponding square (inside the field), will grow in the corresponding position;
  5. The control of the field position is divided into squares. Each area where plants can be planted is controlled by a small square, and plants are planted in the corresponding square. After selecting a card, moving the mouse to the field will mark a square area, indicating that plants are planted in this area.
  6. Pea seedlings were planted, the timing of bullets, when the bullet the location and the location of the zombie intersection, is to hit (processing shot animation, the bullet disappear, zombies to deduct the corresponding health, hit the audio, etc.), and blood zombies will stop moving animation after zero, open new animated to the ground, the ground after the completion of the delete zombies, the cumulative score of at the same time;
  7. When the position of zombies and plants meet, zombies will stop the animation of walking, start the animation of eating (plants are deducted from the health, zombies eat sound), plant objects will be cleaned up after the plant health is zero;
  8. Sunshine there are two ways, produce and sunflower producing regularly, will open after the creation of animation you swing down to stop the animation, after certain limits open counter (currently set to 10 seconds), count to zero without the sun still is not click on the collection will disappear, click on the sun within a specified time (sound), will be open to the upper left corner flying animation, After the end of the sun disappeared, the sun increased (sound);
  9. End condition: 1) The zombie touched the leftmost part of the field – judged failure. 2) Score 300– a victory!

implementation

Draw the background

Framework.prototype. drawBG=function(){var image,img,sx=150,sy=0,sWidth=900,sHeight=600,dx=0,dy=0,dWidth=900,dHeight=600; // Background image = this.imgobj [1]; img = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); this.renderArr.push(img); }Copy the code

Draw the upper card area, integral area and related buttons

/ / draw the game at the top of the related picture (card, etc.) the Plants. The prototype. DrawCard = function () {var image,img,sx=0,sy=0,sWidth=446,sHeight=87,dx=0,dy=0,dWidth=446,dHeight=80; // Image = this.imgObj[2]; img = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); this.renderArr.push(img); sWidth=128,sHeight=31,dx=450,dy=0,dWidth=128,dHeight=40; Image = this.imgobj [12]; img = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); this.renderArr.push(img); sWidth=50,sHeight=70,dx=76,dy=5,dWidth=50,dHeight=68; // Image = this.imgObj[3]; img = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); img.sunCost=50; Img. Type ='sun'; // Plant type this.renderarr.push (img); this.cardArr.push(img); sWidth=50,sHeight=70,dx=130,dy=4,dWidth=50,dHeight=70; // Image = this.imgObj[4]; img = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); img.sunCost=100; Img. Type ='wandou'; // Plant type this.renderarr.push (img); this.cardArr.push(img); sWidth=97,sHeight=33,dx=780,dy=8,dWidth=97,dHeight=33; Image = this.imgObj[5]; img = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); this.startImage=img; this.renderArr.push(img); sWidth=97,sHeight=33,dx=650,dy=8,dWidth=97,dHeight=33; Image = this.imgobj [8]; img = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); this.createZombiesImage=img; this.renderArr.push(img); }Copy the code

Click start logic

Click “Start” to enter the game. Most functions of the game are realized in this logic, including:

Show the starting picture, open the background music, sunshine score display, score display, create the background square of the field, create the background square of the card, open the general mission, regularly create sunshine, regularly create zombies.

Show start picture

/ / show pictures to the Plants. The prototype. StartShow = function () {var image,img,sx=0,sy=0,sWidth=225,sHeight=108,dx=this.w/2-110,dy=this.h/2-100,dWidth=225,dHeight=108; image = this.imgObj[10]; img = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); this.renderArr2.push(img); var that=this; setTimeout(function(){ that.clear(img); }, 2000); }Copy the code

Set a delay of 2 seconds to automatically clear the image

Sunlight scoring display

/ / create the sun points the Plants. The prototype. CreateSunText = function () {x = 40, y = 74, the content = this. SunTotalCount; var text = new _.Text({ x:x, y:y, text:content, font:'20px ans-serif', textAlign:'center', fill:true, fillStyle:'green' }); this.renderArr2.push(text); this.sunCountObj=text; }Copy the code

Integral display

/ / create the integral the Plants. The prototype. CreateCountText = function () {x = 530, y = 34, the content = this. CurCount; var text = new _.Text({ x:x, y:y, text:content, font:'30px ans-serif', textAlign:'center', fill:true, fillStyle:'pink' }); this.renderArr2.push(text); this.countObj=text; }Copy the code

Create a background square for cards (to listen for mouse clicks on cards)

The coordinates and width and height of the square correspond to the card array elements, and the fillStyle of the square is processed using RGBA, as in: Rgba (192,192,192,0) rgba(192,192,192,0.6), cards are available when the last digit is 0, and when 0.6, cards are masked and unusable (unusable is controlled by mouse click, The mouse click is controlled by the parameter alive, which is true to indicate that the mouse click is available and false to indicate that the mouse click is invalid.

/ / create card background square the Plants. The prototype. CreateCardBGRect = function () {var x = 0, y = 0, the rect, the fillStyle alive; for(var i=0; i<this.cardArr.length; i++){ var item=this.cardArr[i]; fillStyle = this.sunTotalCount>=item.sunCost? 'rgba (192192192, 0)' : 'rgba (192192192,0.5)'; alive = this.sunTotalCount>=item.sunCost? true:false; rect = new _.Rect({ x:item.dx, y:item.dy, width:item.dWidth, height:item.dHeight, fill:true, fillStyle:fillStyle }) rect.sunCost=item.sunCost; // Set the amount of sunlight to be spent rect.alive=alive; rect.type=item.type; this.renderArr2.push(rect); this.cardRectArr.push(rect); }}Copy the code

Create a background square for the field (to monitor plant planting)

Set X and Y coordinates and width and height according to the specifications of the background field, so that the square created will correspond to the background, and it is easier to control when planting plants, explained as follows:

The picture above is my own random drawing, not well drawn, not all drawn, in fact, each inside, and relatively neat, I modify the code a little screenshots, the final code is definitely not like this oh

In this way, the area of the field is covered piecemically, but we also use RGBA to highlight the plants

/ / create a square the Plants. The plant field background prototype. CreateBGRect = function () {var x = 0, y = 0, the rect. for(var i=1; i<=5; I ++){//5 line y = 75+(I -1)*100; for(var j=1; j<=9; J ++){//9 column x = 105+(j-1)*80; rect = new _.Rect({ x:x, y:y, width:80, height:100, fill:true, //fillStyle:_. GetRandomColor () fillStyle:'rgba(0,250,154, 0)'}) rect.index= I; This.renderarr2. push(rect); this.bgRectArr.push(rect); }}}Copy the code

To create the sun

1, Sunflowers and sunflowers are both placed here, the difference is that the X coordinates of the sunflowers are randomly created, while the X and Y coordinates of sunflowers are based on the position of the sunflower.

2. Set the score of sunlight, the amount of sunlight’s health, and the end position of sunlight’s default movement (this position can be determined by yourself, I define the Y coordinate is 400). Why does sunlight have the amount of health? This volume is used to control the disappeared time, the blood I set for 100, for example, when the sun movement, the up and bottom blood will open computing task, once every 100 milliseconds to perform, let blood – 1, for 100 milliseconds performed 10 times are 1 second, 1 seconds after they became 90 health, when HP to zero if there is no to collect the sunlight, You need to let the sunlight disappear and turn off this timer.

Math.atan2 calculates the Angle based on where the sun is clicking and the position of the upper corner, and then calculates the X and Y values based on the Angle using Math.cos and Math.sin. The timer will move according to this value.

4. After moving the specified position, do the following actions: clear the motion timer, sunlight accumulation and display, collect sound effects, sunlight disappearance, update the available status of cards.

/ / create the Plants sunshine. Prototype. CreateSun = function (plant) {var image,sun,sx=0,sy=0,sWidth=77,sHeight=74,dx=0,dy=70,dWidth=45,dHeight=44; If (plant){// this is the sun created by the plant dx = plant.dx; dy = plant.dy; } else {dx = _. GetRandom (200800); Var startKey=this.count+this.zombiesRunCount+this.wandousRunCount+ this.zombiesdeadCount +1; // Image = this.imgObj[startKey]; sun = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); sun.imageKey=startKey; // Execute animation update subscript sun.key=startKey; // Original subscript sun.value=20; // Collect a 20分 Sun. Blood =100; // Default 10 blood points (10 seconds disappear, because I set the sun to 100 milliseconds, so this blood is set to 100, -1 each time, 10 seconds is exactly 100) sun.floor=400; This.renderarr2. push(sun); this.suns.push(sun); sun.timmer = setInterval(animate.bind(this,sun),100); function animate(z){ var that=this; z.imageKey ++; If (z.imageKey>=(thate.sunrunCount +z.key)){z.imageKey=z.key; } z.image = that.imgObj[z.imageKey]; z.dy+=2; If (z.dy>=z.floor){//console.log(' sun is in position '); clearInterval(z.timmer); Sun.timmer = setInterval(time.bind(this,sun),100); Function time(z){var that=this; z.imageKey ++; If (z.imageKey>=(thate.sunrunCount +z.key)){z.imageKey=z.key; } z.image = that.imgObj[z.imageKey]; Z.blood --; if(z.blood<=0){ clearInterval(z.timmer); //console.log(' The sun is out of time '); fade.call(this,z); Function fade(z){this.clear(z); //console.log(' The sun disappeared '); this.clearAssign(this.suns,z); // explicitly specify object z=null; } function sunClick(z){//console.log(' sun is clicked ') clearInterval(z.timmer); This.pointsmusic.play (); var cx=cy=20; Var Angle = math.atan2 ((z.dy-cy), (z.dx-cx)) var mx = my=0; mx = Math.cos(angle)*20; my = Math.sin(angle)*20; z.mx=mx,z.my=my; Z.timmer = setInterval(suncollect. bind(this,z),100); Function sunCollect(z){var that=this; z.imageKey ++; If (z.imageKey>=(thate.sunrunCount +z.key)){z.imageKey=z.key; } z.image = that.imgObj[z.imageKey]; z.dx-=z.mx; z.dy-=z.my; If (z.d y < = 20 | | z.d x < = 20) {/ / console log (' the sun is collected); clearInterval(z.timmer); this.moneyfallsMusic.play(); fade.call(this,z); SunTotalCount +=z.value; sunTotalCount+=z.value; // Update whether the card is available that.updatecardUse (); Suncountobj. text= that.suntotalCount; } } sun.click=sunClick.bind(this,sun); // Bind the sun object to the function}Copy the code

Create a zombie

1. Create zombies: timing (10 seconds), random number (1-5), random lines (1-5 lines, which means which line on the map).

2. Set the health of the zombie, the number of lines the zombie is in, and the state of the zombie (run, eat, dead). The state is used to control the subscript of switching pictures, otherwise the animation will make mistakes.

3. Walking animation relies on switching pictures and changing the X coordinate (decreasing X coordinate by 2 per frame).

4. Each frame should judge whether the X coordinate meets the coordinate of the plant. If the animation of walking is closed first, update the state to EAT, open the animation of eating, and switch the subscript of the picture.

5. Each time you eat, decrease the amount of blood of the plant and judge the amount of blood of the plant. If the amount of blood returns to zero, it means that you have finished eating. If you don’t finish, keep eating.

6, each frame also to determine whether the zombie’s X coordinate to the left, if the game is over.

create

/ / create a zombie the Plants. The prototype. CreateZombie = function () {var image,zomble,sx=0,sy=0,sWidth=75,sHeight=119,dx=900-75,dy=270,dWidth=75,dHeight=119; Var index = _. GetRandom (1, 6); If (index==1){dy=60; }else if(index==2){ dy=160; }else if(index==3){ dy=260; }else if(index==4){ dy=355; }else if(index==5){ dy=460; } var startKey=this.count+1; // Image = this.imgObj[startKey]; zomble = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); zomble.imageKey=startKey; // Execute animation update subscript zomble. Key =startKey; // Original subscript zomble. Blood =10; Zomble. Index =index; Zomble. State ='run'; this.renderArr2.push(zomble); this.zombies.push(zomble); zomble.run=run.bind(this); zomble.run(); function run(){ zomble.timmer = setInterval(animate.bind(this,zomble),100); } function animate(z){ var that=this; z.imageKey ++; If (z.imageKey>=(thate.zombiesRunCount +z.key)){z.imageKey=z.key; } z.image = that.imgObj[z.imageKey]; z.dx-=2; That. Eat (zomble) if(z.dx<=100){console.log(' finished '); that.end(); }}}Copy the code

Zombies eat

Function (zomble){// This is an example of an example of a zomble. // This is an example of an example of a zomble. var plant; For (var I =0; i<plants.length; i++){ var item=plants[i]; If (item.index==zomble.index){if(item.dx+ item.dwidn-20 >=zomble.dx){// If (item.index==zomble.index){// If (item.dx+ item.dwidn-20 >=zomble.dx){// break; } } } if(plant){ clearInterval(zomble.timmer); // Clear the moving animation zomble.imageKey=zomble.key=this.count+this.zombiesRunCount+this.wandousRunCount+this.zombiesDeadCount+this.sunRunCount+1 ; // set key zomble. State ='eat'; zomble.timmer = setInterval(animate.bind(this,zomble,plant),100); } function animate(z,p){ this.eatMusic.play(); var that=this; z.imageKey ++; If (z.imageKey>=(thate.zombieseatCount +z.key)){z.imageKey=z.key; } z.image = that.imgObj[z.imageKey]; p.blood--; / / plant health to deal with the if (p.b lood < = 0) {/ / console log (' plants are eaten '); clearInterval(z.timmer); // Remove the plant this.delplant (p); zomble.state='run'; zomble.imageKey=zomble.key=this.count+1; // set key // continue to move z.run(); }}}Copy the code

Delete the plant

/ / delete the plant the Plants. The prototype. DelPlant = function (plant, type) {if (! Type){// Plants that have not been created do not need to clear these two tasks // Stop the animation of the plant itself clearInterval(plant.timmerSelf); // Stop animating plants firing bullets clearInterval(plant.timmer); } // Delete this.clear(plant) from render; // Plants array to delete this.clearassign (this.plants,plant); If (plant.bgrect){plant.bgrect.alive =false; plant.bgRect.plant=false; } plant=null; }Copy the code

Create sunflower

1, click on the card to create, so it must be passed the mouse position, create with the mouse move (at this time the sunflower has been created)

2. Set the alive function. When the position is selected in the field, execute this function to carry out the planting operation.

3. Deduct the sunshine cost, update whether the card is available, and open the task of generating sunshine on time

/ / create the sun plant the Plants. The prototype. CreateSunPlant = function (pos, item) {var image,plant,sx=0,sy=0,sWidth=63,sHeight=73,dx=110,dy=300,dWidth=63,dHeight=73; dx = pos.x,dy=pos.y; // Set the initial position to the mouse position // draw the picture subscript var startKey=this.count+this.zombiesRunCount+this.wandousRunCount+this.zombiesDeadCount+this.sunRunCount+this.zombiesEatCoun t+1; // Image = this.imgObj[startKey]; plant = new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); plant.imageKey=startKey; // Execute animation update subscript plant.key=startKey; // Original subscript plant.suncost = item.suncost; // Plant. Blood =50; Id ='SunPlant'; this.renderArr2.push(plant); this.plants.push(plant); this.currPlant=plant; // Mark the plant being created: plant.alive=alive.bind(this); Function alive(bgRect){// Set the background object plant.bgrect =bgRect; // This. SunTotalCount -= plant.suncost; // Update whether the card is available this.updatecardUse (); // Update suncount this.suncountobj. text=this.sunTotalCount; Plant.timmer = setInterval(shoot.bind(this),6000); this.plantMusic.play(); } function shoot(){this.createsun (plant); } // Animate plant. TimmerSelf = setInterval(animate. Bind (this,plant),100); function animate(p){ var that=this; p.imageKey ++; If (p.imageKey>=(thate. sunPlantRunCount+p.key)){p.imageKey=p.key; } p.image = that.imgObj[p.imageKey]; }}Copy the code

Click the card and move the mouse. The sunflower will follow the mouse and move to the square position of the field. The color of the square will be highlighted.

Creating pea Plants

1, similar to sunflower creation, except sunflower creation is sunshine, pea plant creation is small peas, can attack zombies.

2, the bullet in the movement, determine whether to contact with the zombie, if the contact will execute the hit animation, delete the bullet, subtract the zombie blood, if the zombie death, then open the zombie death animation, increase points.

create

/ / create the peas the Plants. The prototype. CreateWandou = function (plant) {var image,img,sx=0,sy=0,sWidth=28,sHeight=28,dx=plant.dx+50,dy=plant.dy,dWidth=28,dHeight=28; Var startKey=6; // Image = this.imgObj[startKey]; var wandou= new _.ImageDraw({image:image,sx:sx,sy:sy,sWidth:sWidth,sHeight:sHeight, dx:dx, dy:dy ,dWidth:dWidth,dHeight:dHeight}); this.renderArr2.push(wandou); wandou.index=plant.index; Shootmusic.play (); shootmusic.play (); Timmer = setInterval(wandouMove. Bind (this,wandou),100); function wandouMove(wandou){ wandou.dx+=10; Var flag = this.hit(wandou); If (flag | | wandou. Dx > 850) {/ / hit the target or beyond the border clearInterval (wandou. Timmer); If (flag){// Hit the target // create a picture of the bullet hit this.hitanimate (wandou); this.hitMusic.play(); // Hit the music} // Clear the bullet this.clear(wandou); wandou=null; }}}Copy the code

Hit the target

Hit =function(obj){var arr = this.zombies; For (var I =0; i<arr.length; i++){ var item = arr[i]; If (item.dx<=obj.dx+ obj.dwidth && obj.index==item.index){// Bullet function should be equal to zombie line count. If (item.blood==0){// Kill the zombie clearInterval(item.timmer); if(item.state=='run'){ item.imageKey=item.key=item.key+this.zombiesRunCount+this.wandousRunCount; }else if(item.state=='eat'){item.imageKey=item.key=item.key- this.sunruncount -this.zombiesDeadCount; } item.state='dead'; this.addCount(); // add the integral this.dead(item); // Death animation arr.splice(I,1); } return true; }}}Copy the code

Add Event Control

// add a mouse movement event to the canvas2 canvas (because canvas2 is on top) canvas2.addEventListener('mousemove', this.mousemove.bind (this)); // add a mouseClick event to the canvas2 canvas (because canvas2 is on top) canvas2.addeventlistener ('click', this.mouseclick.bind (this)); // add the right mouse button event to the canvas2 canvas (because canvas2 is on it) canvas2.addEventListener('contextmenu', this.contextmenu.bind (this));Copy the code

Mouse movement event

/ / mouse event the Plants. The prototype. MouseMove = function (e) {var that = this; if(that.gameOver) return ; // If (! this.startImage) return; Var pos = _.getoffSet (e); Var isCatch = this.startimage.ispoint (pos); // Mouse capture if(! isCatch && this.gameAlive){ isCatch = this.createZombiesImage.isPoint(pos); } if(! isCatch){ if(this.gameAlive && ! This.currplant) {// The game starts and no plants are being created // Loop the card background array for(var I =0; i<this.cardRectArr.length; i++){ var item=this.cardRectArr[i]; If (item.ispoint (pos) && item.alive){// mouse capture isCatch=true; break; } } } } if(! IsCatch){// for(var I =0; i<this.suns.length; i++){ var item=this.suns[i]; If (item.ispoint (pos)){// mouse capture isCatch=true; break; } } } var plant = this.currPlant; if(! IsCatch){if(plant){for(var I =0; i<this.bgRectArr.length; i++){ var item=this.bgRectArr[i]; if(item.isPoint(pos) && ! Item.plant){// Mouse capture, and currently no plant isCatch=true; Item. The fillStyle = "rgba (0250154, 0.5); } else {item. The fillStyle = "rgba (0250154, 0)"; } } } } if(isCatch){ this.el.style.cursor = 'pointer'; }else{this.el.style. Cursor = "; If (plant){plant.dx=pos.x; plant.dy=pos.y; } this.render2(); }Copy the code

Mouse click event

/ / mouse click event the Plants. The prototype. MouseClick = function (e) {if (this. GameOver) return; Var that=this; var that=this; var pos = _.getOffset(e); Var isCatch = thate.startimage.ispoint (pos); If (isCatch){that.start(); } if(! isCatch && this.gameAlive){ isCatch = this.createZombiesImage.isPoint(pos); If (isCatch){that.createzombie (); } } if(! isCatch){ if(this.gameAlive && ! This.currplant) {// The game starts and no plants are being created // loop card array for(var I =0; i<this.cardRectArr.length; i++){ var item=this.cardRectArr[i]; If (item.ispoint (pos) && item.alive){// mouse capture isCatch=true; CreatePlant (pos,item); // Create a new pea sprout, follow the mouse move this.createPlant(pos,item); // create plant break; } } } } if(! IsCatch){// for(var I =0; i<this.suns.length; i++){ var item=this.suns[i]; If (item.ispoint (pos)){// Mouse capture item.click && item.click(); break; } } } if(! isCatch){ var plant = this.currPlant; If (plant){for(var I =0; i<this.bgRectArr.length; i++){ var item=this.bgRectArr[i]; if(item.plant) continue; // Skip if(item.ispoint (pos)){// mouse catch isCatch=true; plant.dx=item.x+10; plant.dy=item.y+20; plant.index=item.index; // Set the number of rows for plant. Alive (item); // plant item.plant=true; Item. fillStyle="rgba(0,250,154, 0)"; this.currPlant=null; break; } } } } }Copy the code

Right mouse button event

/ / right click event the Plants. The prototype. The contextMenu = function (e) {var e = e | | window. The event; // Unclick the default event e.preventDefault && e.preventDefault(); if(this.gameOver) return ; // If (! this.startImage) return; // if(! this.gameAlive)return; console.log('oncontextmenu'); // Delete this.delPlant(this.currPlant,1); this.currPlant=null; For (var I =0; i<this.bgRectArr.length; i++){ var item=this.bgRectArr[i]; Item. The fillStyle = "rgba (0250154, 0)"; }}Copy the code

conclusion

The basic functions have been realized, but there are many functions that have not been realized. I really have no time to do it. I have to go to work. You can’t live like the guy in this room who made hundreds of millions:

1. After you finish, you must refresh the page to start again (” click start “button).

2, the card supports less crops, crops can not be replaced with shovels.

3, no pass feeling, no car crush zombie scene, etc. (not to mention many more…) .

As a complete game, there’s a lot of features to be done, a lot of improvements to be made, and a lot of code to be refactored; But as a practice, learning, sharing ideas, I think it is enough.

It took me a while to write it out, but you can see it here.

Welcome to like + comment + attention, thank you!

Pay attention to the public number [programming world mingshi hidden], reply [129] download source code, at the same time there are more information, example code, interview skills!