js最终章之挑战不可能

目录

小球碰撞游戏

手动控制小球

三国英雄归位

未来之星 


小球碰撞游戏

要求:点击边框内部任何地方,小球都会向上方任意一点移动,当小球移动到上边框时,会发生镜像反弹,向其他方法移动,游戏开始后,下方会有一个挡板,通过小键盘控制挡板,当小球下落时,如果在挡板上,则反弹,游戏继续;否则,游戏结束

onclick属性表示设置一个鼠标点击事件,后面跟函数名

Math.random()方法表示随机生成一个(0,1]的数

Math.floor()方法表示将里面的值向下取整

Math.ceil()方法表示将里面的值向上取整

document.οnkeydοwn=function(e)解读

docment.onkeydown()方法表示创建一个键盘事件

function表示是一个函数,(e)表示参数,e.keyCode表示获取建盘按键的Unicode

思路分析:

1、首先我们需要一个方框里面存放一个小球(通过div + css即可实现)

2、然后我们需要对方框设置一个onclick鼠标单击事件,当我们在方框内单击鼠标时,小球会向上移动(js-dom事件实现)

3、如何使小球向上移动,我们需要获取小球球心的坐标,并在页面上随机生成一个判定点,设判定点的x坐标为r,y坐标就是50,所以判定点坐标为(r,50)

4、让小球向判定点移动。小球向那个方向移动分解为x轴移动和y轴移动,我们将这两个方向的位移分别设为▲x和▲y,因为球心坐标已知,我们就可以计算出▲y,然后我们用y来计算▲x。根据微积分可知,dy=-1,dx= ▲x/▲y *dy,就可计算出dx的长度,那么就可以计算出x

5、此时判定点和小球的坐标都可通过▲y来表示,

    let x_y = (x-r)/(y-50),这里x_y就是▲x/▲y
    let dy = -1
    let dx = x_y * dy

6、在点击事件中,创建一个定时器,控制小球向上移动,因为判定点是随机出现的,所以小球就是随机向上移动的,当小球触碰到边框之后,会发生镜面反弹

7、根据画图可知,小球触碰到上下边框时,x轴移动方向不变,y轴移动方向改变;小球触碰到左右边框时,y轴移动方向不变,x轴移动方向改变

8、在定时器中添加判定条件,控制小球方向改变

if(y<=50 || y>=750){

         dy = -dy
 }

 if(x<=50 || x>=1150){
         dx = -dx
 }

<style>
	.f{
		position: relative;
		width: 1200px;
		height: 800px;
		border: 1px solid red;
	}
	.z{
		position: absolute;
		width: 100px;
		height: 100px;
		background-color: aqua;
		border-radius: 50%;
		top: 350px;
		left: 550px;
	}
	.db{
		position: absolute;
		width: 400px;
		height: 20px;
		background-color: red;
		left: 400px;
	}
</style>

<body>
	<div class="f" onclick="pengz()">
		<div id="z" class="z"></div>
	</div>
	<div id="db" class="db" onclick="fant()"></div>
</body>
<script>
	// 生成0~1200的随机数
	let r = Math.floor(Math.random()*1200)
	// 小球与上边缘碰撞点的坐标为,(r,50)
	// 设置小球的圆心
	let x =600,y=400
		
	// 设置其运动距离
	let x_y = (x-r)/(y-50)
	let dy = -1
	let dx = x_y * dy
		
	// 接收值
	let z=document.getElementById('z')
		
	function pengz(){
			
		// 创建一个定时器
		setInterval(()=>{
			if(y<=50 || y>=750){
				dy = -dy
			}
			if(x<=50 || x>=1150){
				dx = -dx
			}
			x+=dx
			y+=dy
			z.style.left = x-50 +'px'
			z.style.top = y-50 + 'px'
		},5)
	}
		
	// 设置挡板的移动速度
	let vx = 25;
	
	// 获取值
	let db=document.getElementById('db')
		
	// 设置挡板的x和y坐标	
	let x0 = 600
	let y0 = 780
	// 设置挡板的上边缘
	let x1=0;
	let y1=0;
		
	// 小球与挡板碰撞点(k,50)
		
	document.onkeydown=function(e){
		switch(e.keyCode){
			case 37:
				console.log('左')
				x0 -= vx
				db.style.left= x0-150+'px'
				break
			case 39:
				console.log('右')
				x0 += vx
				db.style.left= x0-150+'px'
				break
		}
	}
		
</script>

手动控制小球

要求:通过键盘事件,控制小球的上下左右移动

document.οnkeydοwn=function(e)解读

docment.onkeydown()方法表示创建一个键盘事件

function表示是一个函数,(e)表示参数,e.keyCode表示获取建盘按键的Unicode

在js中,小键盘的上 下 左 右移动的keyCode值分别是38 40 37 39

<style>
	.f{
		position: relative;
		width: 900px;
		height: 600px;
		border: 1px solid red;
	}
	.z{
		position: absolute;
		width: 100px;
		height: 100px;
		background-color: cornflowerblue;
		border-radius: 50%;
	}
</style>

<body>
	<div class="f">
		<div id="z" class="z"></div>
	</div>
</body>
<script>
	// 设置小球圆心坐标
	let x = 50,y = 50
		
	// 设置小球每次移动的距离(移动速度)
	let dy = 20;
	let dx = 20;
		
	// 获取元素
	let z=document.getElementById('z')
		
	// 创建键盘事件
	document.onkeydown=function(e){
		console.log(e.keyCode,typeof e.keyCode)
		/* 上38 下40 左37 右39 */
		switch(e.keyCode){
			case 38:
				console.log('上')
				y -= dy
				z.style.top= y-50+'px'
				break
			case 40:
				console.log('下')
				y += dy
				z.style.top= y-50+'px'
				break
			case 37:
				console.log('左')
				x -= dx
				z.style.left= x-50+'px'
				break
			case 39:
				console.log('右')
				x += dx
				z.style.left= x-50+'px'
				break
		}
	}
</script>

三国英雄归位

 要求:将上方的图片通过键盘移动到下方所对应的区域中去。鼠标单击选中一个图片,通过键盘移动到对应的位置。可以随时选中其他的图片来移动


 操作单个元素,布局方式:

  • 子元素绝对定位,父元素相对定位
  •  所有的子元素,left和top都是相对于父元素的左上顶点
  •  因此每个子元素的left和top的初始值都不一样

            
 操控批量的元素:

  • 父元素流式布局flex,子元素相对定位
  • 每个子元素都是相对于自身的初始位置
  • 每个子元素的left和top初始值都是0

display:flex属性表示流式布局justify-contend表示操作每个子元素

text-align属性表示文本水平居中,line-height:值,当值等于盒子的高度时,文本垂直居中

onclick鼠标单击事件,如果函数名里面包含this表示当前对象

<style>
	.f1,.f2{
		/* 流式布局,批量操作 */
		display: flex;
		/* 每个子元素均匀分布 */
		justify-content: space-around;
	}
	.f1>img{
		width: 200px;
		height: 300px;
        /* 注意这里子元素一定要设置成相对定位 */
		position: relative;
		top: 0px;
		left: 0px;
	}
	.f2{
		margin-top: 150px;
	}
	.f2>div{
		width: 200px;
		height: 300px;
		border: 1px solid slateblue;
		/* 文本水平居中 */
		text-align: center;
		/* 文本垂直居中 */
		line-height: 300px;
	}
</style>

<body>
	<!-- move(this)鼠标点击之后获取到当前被点击的对象 -->
	<!-- move(this,0)这里括号里面的值表示数组的下标 -->
	<div class="f1">
		<img src="imgSG/曹操.jpg" alt="" onclick="move(this,0)">
		<img src="imgSG/貂蝉.webp" alt="" onclick="move(this,1)">
		<img src="imgSG/关羽.webp" alt="" onclick="move(this,2)">
		<img src="imgSG/刘备.jpg" alt="" onclick="move(this,3)">
		<img src="imgSG/刘协.webp" alt="" onclick="move(this,4)">
		<img src="imgSG/孙权.webp" alt="" onclick="move(this,5)">
	</div>
		
	<div class="f2">
		<div>刘协</div>
		<div>刘备</div>
		<div>关羽</div>
		<div>曹操</div>
		<div>孙权</div>
		<div>貂蝉</div>
	</div>
</body>
<script>
		
	// 设置一个对象坐标,记录当前操作元素的坐标
	// 注意这里因为只有一个对象坐标,所以每个图片使用的都是该对象坐标
	let pos = {x:0,y:0}
		
	// 创建一个数组对象,来存放6个对象的坐标
	let arr = [{x:0,y:0},{x:0,y:0},{x:0,y:0},{x:0,y:0},{x:0,y:0},{x:0,y:0}]
		
	function move(img,i){
		pos = arr[i]
		// 创建键盘事件控制图片移动
		document.onkeydown= function(e){
			switch(e.keyCode){
				case 38:
					console.log('上')
					pos.y -= 10
					img.style.top =pos.y + 'px'
					break
				case 40:
					console.log('下')
					pos.y -= 10
					img.style.top =pos.y + 'px'
					break
				case 37:
					console.log('左')
					pos.x -= 10
					img.style.left =pos.x + 'px'
					break
				case 39:
					console.log('右')
					pos.x += 10
					img.style.left =pos.x + 'px'
					break
			}
		}
	}
</script>

未来之星 

要求:上半区域图片开始时是默认的,下半区域图片是可以点击投票的。

当我们将鼠标移动到图片上面时,图片有会产生阴影并向右下角移动

我们投票之后,票数会自动增加,系统会自动进行排序,排序之后会和前三名比较,并进行替换。

<style>
	.top{
		/* 采用流式布局 */
		display: flex;
		/* 子元素居中显示 */
		justify-content: center;
	}
	img{
		width: 150px;
		height: 200px;
		border-radius: 8px;
	}
	.top>div{
		text-align: center;
		margin-left: 30px;
	}
	.top>div:nth-child(1),.top>div:nth-child(3){
		margin-top: 30px;
	}
	.top span{
		color: coral;
	}
	/* 用于选择鼠标指针浮动在上面的元素 */
	img:hover{
		/* 设置X轴偏移量、Y轴偏移量、模糊半径、扩散半径和颜色 一一对应关系*/
		box-shadow: 5px 5px 5px rebeccapurple;
		/*
			在水平和/或垂直方向上重新定位元素,这里向右下角移动 
			括号里面一个参数向右移动,两个参数向右下角移动
		*/
		transform: translate(5px,5px);
	}
	.main{
		display: flex;
		/* 子元素均匀分布 */
		justify-content: space-around;
		flex-wrap: wrap;
	}
	.main>div{
		text-align: center;
		margin-left: 20px;
	}
	button{
		width: 90px;
		height: 40px;
		/* 取消边框 */
		border: none;
		/* 大号字体 */
		font-size: larger;
		background-color: rebeccapurple;
		color: white;
		border-radius: 10px;
	}
	button:hover{
		/* 设置X轴偏移量、Y轴偏移量、模糊半径、扩散半径和颜色 一一对应关系 */
		box-shadow: 0px 8px 5px palevioletred;
	}
	/*  伪类匹配被用户激活的元素。当用鼠标交互时,它代表的是用户按下按键和松开按键之间的时间 */
	button:active{
		/* 在垂直方向使元素重新定位 */
		transform: translateY(5px);
		/*  设置X轴偏移量、Y轴偏移量、模糊半径、扩散半径和颜色 一一对应关系 */
		box-shadow: 0px 3px 5px palevioletred;
	}
</style>

<body>
	<h1 style="text-align: center; color: blue;">未来之星前三甲</h1>
	<div class="top" id="top">
		<div>
			<img src="imgs/a.webp" alt=""><br>
			<span>榜眼</span><br>
			张三--90
		</div>
		<div>
			<img src="imgs/b.webp" alt=""><br>
			<span>状元</span><br>
			李四--100
		</div>
		<div>
			<img src="imgs/c.jpeg" alt=""><br>
			<span>探花</span><br>
		    王五--80
		</div>
	</div>
	<hr />
	<div class="main" id="main">
		<!-- 先玩成一个图片的设置 -->
		<div>
			<img src="./imgs/a.webp" alt=""><br>
			<span>a--0</span><br><br>
			<button>投票</button>
		</div>
	</div>
</body>

<script>
// 将所有图片元素存入数组
	let beauty = [
		{name:'a.webp',num:0},{name:'b.webp',num:0},{name:'c.jpeg',num:0},
		{name:'d.webp',num:0},{name:'e.webp',num:0},{name:'f.webp',num:0},
		{name:'g.webp',num:0},{name:'h.webp',num:0},{name:'i.webp',num:0},
		{name:'j.webp',num:0},{name:'k.webp',num:0},{name:'l.webp',num:0},
	]
		
// 根据数组中的数据,自动生成图片到页面
	// 首先获取值
	let main=document.getElementById('main')
	function flushImg(){
		let s = ''
		beauty.forEach((e,i)=>{
			s+= 
			`<div>
				<img src="./imgs/${e.name}" alt=""><br>
				<span>${e.name.slice(0,e.name.indexOf('.'))}--${e.num}</span><br><br>
				<button onclick="vote(${i})">投票</button>
			</div>`
		})
		main.innerHTML=s
	}
		
	// 调用函数,生成图片
	flushImg()
		
// 投票函数
	function vote(i){
		beauty[i].num++
		// 每次更新投票数量后,重新加载一遍原数组
		flushImg()
		// 更新前三甲的信息
		updateTop3()
	}
		
// 更新前三甲
	// 先获取值
	let tops=document.getElementById('top')
function updateTop3(){
	// 拷贝一份原数组,用来进行排序
	let beauty2 = [...beauty]
		
		
	// 使用系统排序方法
	beauty2.sort((e1,e2)=>{
		return e2.num - e1.num
	})
		
	// 获取排序后数组的前三个对象
	beauty2.slice(0,3)
		
	// 进行替换
	tops.innerHTML=
		`<div>
			<img src="imgs/${beauty2[1].name}" alt=""><br>
			<span>榜眼</span><br>
			${beauty2[1].name.slice(0,beauty2[1].name.indexOf('.'))}--${beauty2[1].num}
		</div>
		<div>
			<img src="imgs/${beauty2[0].name}" alt=""><br>
			<span>状元</span><br>
			${beauty2[0].name.slice(0,beauty2[0].name.indexOf('.'))}--${beauty2[0].num}
		</div>
		<div>
			<img src="imgs/${beauty2[2].name}" alt=""><br>
			<span>探花</span><br>
			${beauty2[2].name.slice(0,beauty2[2].name.indexOf('.'))}--${beauty2[2].num}
		</div>`
}
</script>

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无念至此

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值