我的问题
1. 构造函数的使用
2. 为什么不在构造函数里面定义功能,而要在原型链上去写功能?
在构造函数中定义方法,方法也就是函数,函数是引用类型,每一次new 实例化的时候 都会在堆内存新建一个空间存储函数,这样就造成了 内存浪费.在原型上添加方法,那么所的实例化的对象都会共用这个方法,优点就是减小内存占用利于代码复用
我的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>打砖块</title>
<link rel="stylesheet" href="../拉勾网首页/common.css">
<link rel="stylesheet" href="../拉勾网首页/reset.css">
</head>
<style>
.container{
position: relative;
width: 1000px;
height: 550px;
margin: 0 auto;
margin-top: 20px;
border: 2px solid gold;
padding-top: 20px;
padding-left: 40px;
padding-right: 20px;
}
.container .gameBox{
width: 690px;
height: 500px;
border: 2px solid gold;
box-shadow: 3px 3px 7px #999;
position: relative;
}
.container .gameBox ul li{
position: absolute;
width: 69px;
height: 20px;
left: 0;
top: 0;
}
.container .gameBox #bubble{
position: absolute;
width: 25px;
height: 25px;
border-radius: 50%;
background-color:gold;
left: 59px;
top: 466px;
}
.container .gameBox #board{
position: absolute;
background-color: brown;
width: 150px;
height: 8px;
border-radius: 3px;
left: 0px;
top: 492px;
}
.container .showBox{
width: 250px;
height: 500px;
background-color: #555;
}
.container .showBox span{
display: block;
border-bottom: 1px solid #fff;
padding: 20px 0 10px 20px;
color: #fff;
}
.container .showBox span:first-child{
font-weight: bold;
}
.container .showBox span p{
margin-bottom: 10px;
}
.container button{
height: 30px;
width: 80px;
font-size: 13px;
font-weight: bold;
color: #fff;
text-align: center;
background-color:#666;
margin-top: 10px;
margin-left: 310px;
}
.container .alBox{
display: none;
color: #fff;
font-weight: bold;
font-size: 30px;
text-align: center;
line-height: 200px;
position: absolute;
width: 300px;
height: 200px;
background-color: rgba(85, 85, 85, .6);
top: 175px;
left: 250px;
}
</style>
<body>
<div class="container clearfix">
<div class="gameBox left">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div id = "bubble"></div>
<div id = "board"></div>
</div>
<div class="showBox right">
<span>游戏重要信息</span>
<span>
<p>当前时间</p>
<p id="time">加载中...</p>
</span>
<span id="">
<p>游戏状态</p>
<p id="statu">加载中...</p>
</span>
<span id="">
<p>挡板打球次数</p>
<p id="times">加载中...</p>
</span>
<span id="">
<p>游戏得分</p>
<p id="score">加载中...</p>
</span>
</div>
<button>开始游戏</button>
<div class="alBox">游戏结束!</div>
</div>
<script src="./tools.js"></script>
<script>
function $(id){
return document.getElementById(id);
}
function rand(){
var r = Math.floor(Math.random()*256);
var g = Math.floor(Math.random()*256);
var b = Math.floor(Math.random()*256);
var rgb = `rgb(${r}, ${g}, ${b})`;
return rgb;
}
function Blockbreak(){//这是个构造函数,用大驼峰式命名
this.list = document.getElementsByTagName('li');
this.len = this.list.length;//这里不能直接写list, 要写this.list,下面也是!
this.liwidth = changeCss(this.list[0], 'width');
this.liheight = changeCss(this.list[0], 'height');
this.board = $('board');
this.boardtop = changeCss(this.board, 'top');
this.boardleft = changeCss(this.board, 'left');
this.boardwidth = changeCss(this.board, 'width');
this.gameBox = document.getElementsByClassName('gameBox')[0];
this.gbwidth = changeCss(this.gameBox, 'width');
this.gbheight = changeCss(this.gameBox, 'height');
this.bubble = $('bubble');
this.bubbleleft = changeCss(this.bubble, 'left');
this.bubbletop = changeCss(this.bubble, 'top');
this.bubblewidth = changeCss(this.bubble, 'width');
this.bubbleheight = changeCss(this.bubble, 'height');
this.times = 0;
this.score = 0;
this.alBox = document.getElementsByClassName('alBox')[0];
}
Blockbreak.prototype.init = function(){
for(var i = 0; i < this.len; i++){//初始化砖块
changeCss(this.list[i], 'background-color', rand());
changeCss(this.list[i], 'left', i%10*parseInt(this.liwidth) + 'px');
changeCss(this.list[i], 'top', Math.floor(i/10)*parseInt(this.liheight) + 'px');
}
}
Blockbreak.prototype.keydown = function(){
var that = this;//终于知道这里为啥要用that指向this了,因为到下面的函数里,如果直接用this的话,指向的不是构造函数
addEvent(document, 'keydown', function(e){
var event = e || window.event;
if(event.keyCode == 37){
if(parseInt(that.boardleft) <= 0){
changeCss(that.board, 'left', '0px');
}else{
changeCss(that.board, 'left', (parseInt(that.boardleft) - 15) + 'px');
that.boardleft = changeCss(that.board, 'left');//实时更新left值
}
}
if(event.keyCode == 39){
if(parseInt(that.boardleft) >= (parseInt(that.gbwidth) - parseInt(that.boardwidth))){
changeCss(that.board, 'left', (parseInt(that.gbwidth) - parseInt(that.boardwidth)) + 'px');
}else{
changeCss(that.board, 'left', (parseInt(that.boardleft) + 15)+ 'px');
that.boardleft = changeCss(that.board, 'left');
}
}
});
}
Blockbreak.prototype.move =function(){
var that = this;
var timer = null;
var speedX = 2;
var speedY = 2;
timer = setInterval(function(){
//小球运动部分
changeCss(that.bubble, 'left', (parseInt(that.bubbleleft) + speedX) + 'px');
changeCss(that.bubble, 'top', (parseInt(that.bubbletop) - speedY) + 'px');
that.bubbleleft = changeCss(that.bubble, 'left');//实时更新
that.bubbletop = changeCss(that.bubble, 'top');
//小球碰撞反弹
//上
if(parseInt(that.bubbletop) <= 0){
speedY *= -1;
}
if(parseInt(that.bubbletop) >= parseInt(that.gbheight) - parseInt(that.bubbleheight)){
clearInterval(timer);
changeCss(that.alBox, 'display', 'block');
$('statu').innerHTML = '游戏结束';
}
//左右
if(parseInt(that.bubbleleft) <= 0 || parseInt(that.bubbleleft) >= parseInt(that.gbwidth) - parseInt(that.bubblewidth)){
speedX *= -1;
}
//挡板(注意这里用三个if嵌套表示同时满足这些条件)三个方向的情况
if(parseInt(that.bubbletop) + parseInt(that.bubbleheight) >= parseInt(that.boardtop)){
if(parseInt(that.bubbleleft) + parseInt(that.bubblewidth) >= parseInt(that.boardleft)){
if(parseInt(that.bubbleleft) <= parseInt(that.boardleft) + parseInt(that.boardwidth)){
speedY *= -1;
that.times ++;
$('times').innerHTML = that.times;
}
}
}
//和砖块的碰撞
for(var j = 0; j < that.len; j ++){
//以下注释掉的代码这种方式不太行,得换成下面的offsetTop
// var litop = parseInt(changeCss(that.list[j], 'top'));
// var lileft = parseInt(changeCss(that.list[j], 'left'));
if(parseInt(that.bubbletop) <= that.list[j].offsetTop + parseInt(that.liheight)){
if(parseInt(that.bubbleleft) >= that.list[j].offsetLeft){
if(parseInt(that.bubbleleft) <= that.list[j].offsetLeft + parseInt(that.liwidth)){
speedY *= -1;
changeCss(that.list[j], 'display', 'none');
that.score ++;
$('score').innerHTML = that.score;
}
}
}
}
},20)
}
Blockbreak.prototype.btnevent= function(){
var that = this;
var button = document.getElementsByTagName('button')[0];
var now = new Date();
addEvent(button, 'click', function(){
bb.init();
bb.keydown();
bb.move();
for(var j = 0; j < that.len; j ++){
changeCss(that.list[j], 'display', 'block');
}
changeCss(that.alBox, 'display', 'none');
$('time').innerHTML = now.getFullYear() + '/' + parseInt(now.getMonth() + 1) + '/' + now.getDate();
$('statu').innerHTML = '游戏开始';
});
}
var bb = new Blockbreak();
bb.btnevent();
</script>
</body>
</html>