Super Mary HTML5 source code learning------

First we need to know

Each game consists of:

A: Get user input

B: Update game status

C: Processing AI

D: Play music and sound effects

E: Screen display

These behaviors constitute. The main loop of the game is used to process this behavior sequence. You can use setInterval method to poll in javascript. In super Mary, it's this cycle

	//Main cycle
	var mainLoop=setInterval(function(){

		//The time since the last execution (time variation), which can be approximately regarded as sleep at present
		var deltaTime=sleep;
		
		// Update Animation status
		animation.update(deltaTime);
	
		//Use background overlay to clear the previously drawn picture
		context.drawImage(ImgCache["bg"],0,0);
				
		//Draw Animation
		animation.draw(context, x,y);
		
	},sleep);

How to make the game character move? Today, we only learn to let players move in place, that is, Step3_ one

The method to realize the character movement is to display the different action pictures of the spirit picture alternately in the same position on the canvas to form the animation of the character moving in place. Displaying action pictures in different positions on the canvas forms the animation of characters moving back and forth on the canvas.

Firstly, the bomber moves in place on the canvas and displays the moving animation;

Understand the meaning of Sprite image: the so-called sprite image is a large image containing multiple small images. Using it can reduce http requests and improve performance.

Step 1: realize the display of characters

First, show the player character. You need to create the canvas and get the context, load the cached image, call StartDemo, then empty the canvas area and draw the picture with drawImage.

// Page initialization function
function init(){
	
	// Create a canvas and initialize it (we can also write it directly in the form of a label in the page, and then obtain the canvas through id, etc.)
	canvas=document.createElement("canvas");
	canvas.width=600;
	canvas.height=400;
	document.body.appendChild(canvas);
		
	// Get 2d drawing context 
	context= canvas.getContext("2d");
	
	//Load the picture and store it in the global variable ImgCache, 
	// After loading is done, call startDemo.
	ImgCache=loadImage( [ 
			{ 	id : "player",
				url : "../res/player.png"
			},
			{ 	id : "bg",
				url : "../res/bg.png"
			}
		], 
		startDemo );

}

Step 2: FPS=30

The number of frames run per second. The game main cycle polls every 33.3 (1000 / 30) ms

FPS determines the frequency of game screen update and the speed of the main cycle.

There is a conversion formula between sleep and FPS in the main cycle:

Interval = nearest maximum rounding (1000 / FPS), different from rounding, also known as rounding down

	// Some simple initialization, 
	var FPS=30;
	var sleep=Math.floor(1000/FPS);
	
	//Initial coordinates
	var x=0, y=284;

Step 3: use frame animation

Some basic knowledge to understand:

Animation is achieved by drawing a set of frame pictures. There are these key problems in the specific implementation:

  • In what order should a set of frames be drawn?
  • How to control the drawing time of each frame?
  • Where is the frame drawn on the canvas?
  • How to control the content and picture size of the drawn frame?

Strategy: frame Animation control class Animation

// Animation class Animation class
// cfg is a parameter set of Object type, and its attributes will override the attributes with the same name defined in the Animation prototype
function Animation(cfg){
	for (var attr in cfg ){
		this[attr]=cfg[attr];
	}
}

Animation.prototype={
	constructor :Animation ,

	// Frame contained in Animation, type: array
	frames : null,
	// Number of frames contained
	frameCount : -1 ,
	// Image ID (key stored in ImgCache) and string type used 
	img : null,
	// Currently playing frame
	currentFrame : null ,
	// Currently playing frame
	currentFrameIndex : -1 ,
	// Time played
	currentFramePlayed : -1 ,
	
	// Initialize Animation
	init : function(){
		// Get Image object based on id
		this.img = ImgCache[this.img]||this.img;
		
		this.frames=this.frames||[];
		this.frameCount = this.frames.length;
		
		// Play from frame 0 by default
		this.currentFrameIndex=0;
		this.currentFrame=this.frames[this.currentFrameIndex];
		this.currentFramePlayed=0;
	},
	
	
	// Update Animation status Delta time represents the amount of change in time
	update : function(deltaTime){
		//Judge whether the current Frame has been played, 
		if (this.currentFramePlayed>=this.currentFrame.duration){
			//Play next frame
			
			if (this.currentFrameIndex >= this.frameCount-1){
				//If the current is the last frame, frame 0 will be played
				this.currentFrameIndex=0;
			}else{
				//Play next frame
				this.currentFrameIndex++;
			}
			//Set current frame information
			this.currentFrame=this.frames[ this.currentFrameIndex ];
			this.currentFramePlayed=0;
		
		}else{
			//Increase the played time of the current frame
			this.currentFramePlayed += deltaTime;
		}
	},
	
	//Draw Animation
	draw : function(gc,x,y){
		var f=this.currentFrame;
		gc.drawImage(this.img, f.x , f.y, f.w, f.h , x, y, f.w, f.h );
	}
};

Animation is responsible for reading, configuring and updating frame data and controlling the playback of frame data

Read:

Create an Animation object:

	// Create an Animation object
	var animation = new Animation({
		img : "player" ,
		//The animation consists of three frames, corresponding to the first line in the picture
		frames : [
			{x : 0, y : 0, w : 50, h : 60, duration : 100},
			{x : 50, y : 0, w : 50, h : 60, duration : 100},
			{x : 100, y : 0, w : 50, h : 60, duration : 100}
		]
	} );
function Animation(cfg){
	for (var attr in cfg ){
		this[attr]=cfg[attr];
	}
}

//Animation class Animation class //cfg is a parameter set of Object type, and its attributes will override the attributes with the same name defined in the Animation prototype

to configure:

Initialize Animation object:

	// Initialize Animation
	animation.init();

Initialization function code:

	// Initialize Animation
	init : function(){
		// Get Image object based on id
		this.img = ImgCache[this.img]||this.img;
		
		this.frames=this.frames||[];
		this.frameCount = this.frames.length;
		
		// Play from frame 0 by default
		this.currentFrameIndex=0;
		this.currentFrame=this.frames[this.currentFrameIndex];
		this.currentFramePlayed=0;
	},

Update frame data:

		// Update Animation status
		animation.update(deltaTime);

Update function code:

	// Update Animation status Delta time represents the amount of change in time
	update : function(deltaTime){
		//Judge whether the current Frame has been played, 
		if (this.currentFramePlayed>=this.currentFrame.duration){
			//Play next frame
			
			if (this.currentFrameIndex >= this.frameCount-1){
				//If the current is the last frame, frame 0 will be played
				this.currentFrameIndex=0;
			}else{
				//Play next frame
				this.currentFrameIndex++;
			}
			//Set current frame information
			this.currentFrame=this.frames[ this.currentFrameIndex ];
			this.currentFramePlayed=0;
		
		}else{
			//Increase the played time of the current frame
			this.currentFramePlayed += deltaTime;
		}
	},

Play:

Is to draw frame animation:

		//Draw Animation
		animation.draw(context, x,y);
	//Draw Animation
	draw : function(gc,x,y){
		var f=this.currentFrame;
		gc.drawImage(this.img, f.x , f.y, f.w, f.h , x, y, f.w, f.h );
	}

Let's take a look at the knowledge points that frame animation playback needs to master:

1. In what order should a group of frames be played

		// Play from frame 0 by default
		this.currentFrameIndex=0;

2. How to control the drawing time of each frame:

When the previous frame playback is not completed:

			//Increase the played time of the current frame
			this.currentFramePlayed += deltaTime;

When the previous frame is played:

this.currentFramePlayed=0;

3. Where to start painting on the canvas:

	//Draw Animation
	draw : function(gc,x,y){
		var f=this.currentFrame;
		gc.drawImage(this.img, f.x , f.y, f.w, f.h , x, y, f.w, f.h );
	}

4. How to control the content and picture size of the drawn frame:

First of all, the content of the current frame is an array of frames [], followed by the content of the current frame,

Control operation during initialization:

this.currentFrame=this.frames[this.currentFrameIndex];

Currentframeindex: - 1, which can be regarded as an index

When updating:

			//Set current frame information
			this.currentFrame=this.frames[ this.currentFrameIndex ];

Finally, provide the source code:

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<meta http-equiv="Cache-Control" content="no-cache" />


<title>My first Game</title>

<style type="text/css">
body {
	border:none 0px;
	margin:0px;
	padding:10px;
	font-size : 16px;
	background-color : #f3f3f3;
}

canvas {
	border : 1px solid blue; 
}
</style>


<script type="text/javascript">

// Load picture
function loadImage(srcList,callback){
	var imgs={};
	var totalCount=srcList.length;
	var loadedCount=0;
	for (var i=0;i<totalCount;i++){
		var img=srcList[i];
		var image=imgs[img.id]=new Image();		
		image.src=img.url;
		image.οnlοad=function(event){
			loadedCount++;
		}		
	}
	if (typeof callback=="function"){
		var Me=this;
		function check(){
			if (loadedCount>=totalCount){
				callback.apply(Me,arguments);
			}else{		
				setTimeout(check,100);
			}	
		}
		check();
	}
	return imgs;
}

//Define global objects
var ImgCache=null;
var canvas=null;
var context=null;

// Page initialization function
function init(){
	
	// Create a canvas and initialize it (we can also write it directly in the form of a label in the page, and then obtain the canvas through id, etc.)
	canvas=document.createElement("canvas");
	canvas.width=600;
	canvas.height=400;
	document.body.appendChild(canvas);
		
	// Get 2d drawing context 
	context= canvas.getContext("2d");
	
	//Load the picture and store it in the global variable ImgCache, 
	// After loading is done, call startDemo.
	ImgCache=loadImage( [ 
			{ 	id : "player",
				url : "../res/player.png"
			},
			{ 	id : "bg",
				url : "../res/bg.png"
			}
		], 
		startDemo );

}


// Animation class Animation class
// cfg is a parameter set of Object type, and its attributes will override the attributes with the same name defined in the Animation prototype
function Animation(cfg){
	for (var attr in cfg ){
		this[attr]=cfg[attr];
	}
}

Animation.prototype={
	constructor :Animation ,

	// Frame contained in Animation, type: array
	frames : null,
	// Number of frames contained
	frameCount : -1 ,
	// Image ID (key stored in ImgCache) and string type used 
	img : null,
	// Currently playing frame
	currentFrame : null ,
	// Currently playing frame
	currentFrameIndex : -1 ,
	// Time played
	currentFramePlayed : -1 ,
	
	// Initialize Animation
	init : function(){
		// Get Image object based on id
		this.img = ImgCache[this.img]||this.img;
		
		this.frames=this.frames||[];
		this.frameCount = this.frames.length;
		
		// Play from frame 0 by default
		this.currentFrameIndex=0;
		this.currentFrame=this.frames[this.currentFrameIndex];
		this.currentFramePlayed=0;
	},
	
	
	// Update Animation status Delta time represents the amount of change in time
	update : function(deltaTime){
		//Judge whether the current Frame has been played, 
		if (this.currentFramePlayed>=this.currentFrame.duration){
			//Play next frame
			
			if (this.currentFrameIndex >= this.frameCount-1){
				//If the current is the last frame, frame 0 will be played
				this.currentFrameIndex=0;
			}else{
				//Play next frame
				this.currentFrameIndex++;
			}
			//Set current frame information
			this.currentFrame=this.frames[ this.currentFrameIndex ];
			this.currentFramePlayed=0;
		
		}else{
			//Increase the played time of the current frame
			this.currentFramePlayed += deltaTime;
		}
	},
	
	//Draw Animation
	draw : function(gc,x,y){
		var f=this.currentFrame;
		gc.drawImage(this.img, f.x , f.y, f.w, f.h , x, y, f.w, f.h );
	}
};



// Startup function of Demo
function startDemo(){
	
	// Some simple initialization, 
	var FPS=30;
	var sleep=Math.floor(1000/FPS);
	
	//Initial coordinates
	var x=0, y=284;
	
	// Create an Animation object
	var animation = new Animation({
		img : "player" ,
		//The animation consists of three frames, corresponding to the first line in the picture
		frames : [
			{x : 0, y : 0, w : 50, h : 60, duration : 100},
			{x : 50, y : 0, w : 50, h : 60, duration : 100},
			{x : 100, y : 0, w : 50, h : 60, duration : 100}
		]
	} );
	// Initialize Animation
	animation.init();
	
	//Main cycle
	var mainLoop=setInterval(function(){

		//The time since the last execution (time variation), which can be approximately regarded as sleep at present
		var deltaTime=sleep;
		
		// Update Animation status
		animation.update(deltaTime);
	
		//Use background overlay to clear the previously drawn picture
		context.drawImage(ImgCache["bg"],0,0);
				
		//Draw Animation
		animation.draw(context, x,y);
		
	},sleep);

}





	
</script>

</head> 
<body οnlοad="init()"> 


<div align="center"><a href="http://www.linuxidc.com" target="_blank">www.Linuxidc.com</a></div>
</body>
</html>

Added by ridgedale on Thu, 03 Mar 2022 16:08:55 +0200