目录
小球碰撞游戏
要求:点击边框内部任何地方,小球都会向上方任意一点移动,当小球移动到上边框时,会发生镜像反弹,向其他方法移动,游戏开始后,下方会有一个挡板,通过小键盘控制挡板,当小球下落时,如果在挡板上,则反弹,游戏继续;否则,游戏结束
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 * dy6、在点击事件中,创建一个定时器,控制小球向上移动,因为判定点是随机出现的,所以小球就是随机向上移动的,当小球触碰到边框之后,会发生镜面反弹
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>