huya虎牙小程序比赛
21年暑假参加了虎牙小程序比赛,那时本人才大一,发现网上相关的内容实在是少之又少,现在比赛已经结束一个多月了,我来回顾一下自己的学习过程,希望能给以后的比赛者做一个参考。
HTML、CSS、Javascript
这是前端三剑客,一定要学,但重心不要放在这上面,因为如果在这上花费太多的时间和精力,会消耗你对比赛的大量热情,而且huya有自己的开发平台,并不完全兼容前端三剑客,但背后的原理是相同的,所以学到明白道理就够了。
前端学习软件HBuilder X,然后前端学习自行网上或借书学习就行,这方面的资料很多,不做赘述
HBuilder X
Node.js
这算是个工具吧,需要自行安装,网上搜索相关安装教程就可以,有它才可以继续后续的安装
附huya小程序相关文档网址,按照要求一步一步来安装就好
https://dev.huya.com/docs/#/intro/index
为什么要按node,看图,后续会用到,这个在huya小程序文档中都可以看到,在我看来node只是个工具,创建小程序会用到,并不需要深入学习
React Native
直接学习React Native,不要学React,看图,小程序基于react-native实现,不过又不完全一样,我认为这才是学习重点,自己就因为在前端学习花费了太多时间,导致在这里没时间深入学习了。
react-native还是有很多书籍可以学习的,自己当时也在图书馆借了不少书,下面附上react-native中文学习网
https://reactnative.cn/docs/components-and-apis
HY-UI
HY-UI学习网址
https://hd.huya.com/web/hy-ui-doc/teach/
从创建项目的streamer文件中的app.javascript开始编写代码就行,下面是我的路径,项目名称为hello-world
C:\Users\zhang\hello-world\streamer
首先我认为huya这个设计的很鸡肋,好多使用说明都很模糊,还要自己摸索,简简单单一个按钮定位当时就困扰了我很久,我吐了,完全是自己试出来的
import { UI } from '@hyext/hy-ui'
import React, { Component,useRef,
useState,
useCallBack,
useMemo,
useEffect, } from 'react'
import './quse2.hycss'
import { Route, Router } from "@hyext/router";
import { TouchableOpacity } from "react-native";
import Appm from './app'
import End from './end2'
import { NativeUI } from "@hyext-beyond/hy-ui-native";
const { Lottie } = NativeUI;
const { View, Text , Modal, BackgroundImage, Button, Image,Progress } = UI
class App extends Component {
render() {
return (
<Router initialEntries={['/main']}>
<Route path={'/main'} component={ Main }></Route>
<Route path={'/appm'} component={ Appm }></Route>
<Route path={'/end'} component={ End }></Route>
</Router>
)
}
}
class Main extends Component {
constructor (props) {
super(props);
this.anim = React.createRef()
this.state = {
num : 1,
next : 0,
hid:1,
Ready:1,
pan : 1,
val : Math.floor(Math.random()*100),
val_1 : 0,
val_2 : 0,
val_3 : 0,
problem : ["感谢NEU和huya",
"举例说明你不喜欢的直播风格",
"说出一名你喜欢的同类型主播",
"举例说明你喜欢的直播风格",
"如果作为一名游戏主播,你觉得自己属于娱乐主播还是教学主播",
"今年你最后悔的一件事",
"今年你最成功的一件事",
"直播中你做的最尴尬的事是什么",
"生活中你是一个话多的人吗",
"有喜欢的人了吗",
"说出一名你比较欣赏的异性主播",
"说出年少时的梦想",
"如果遇见初恋,你会说什么",
"用三个词来形容自己",
"如果可以换一种直播类型,你想成为什么主播",
"你有freestyle吗",
"请‘朗读’,你看这个面又长又宽,就像这个碗又大又圆",
"平时会看其他主播直播吗?说出其中两个",
"如果此刻有老板送出了火箭你会",
"当你最不知道穿什么颜色的时候,你会选择什么颜色?",
"如果看到自己最爱的人熟睡在你面前你会做什么?",
"唱一首自己平时会哼唱的歌",
"曾经有过最被感动的事是什么?",
"你最想要的3样东西",
"最后一次发自内心的笑是什么时候?",
"如果给你一个机会去世界上任何一个地方旅行你会去",
"如果时间能倒流你希望回到哪一时间?",
"你心目中理想的爱人是什么样子呢",
"最喜欢哪部电影?",
"你的粉丝是你的什么",
"最喜欢的食物是什么",
"今天中午吃的什么",
"你会如何向喜欢的人表白",
"如果你爱的人不爱你怎么办",
"Having * * * before marriage是否已屡见不鲜",
"你在乎别人看你的眼光吗",
"你相信有纯友谊吗",
"哭得最伤心的是哪一次",
"喜欢看的动画片",
"生活支出最大的部分是",
"大学一共挂过几门课",
"你相信有春梦吗",
"最欣赏自己哪个部位",
"说出自己性格上的两个优点",
"平生最成功的一次撒谎",
"你认为男生就该养家吗",
"分手后还能做普通朋友吗",
"爱情重要游戏重要",
"游戏刚开局,女朋友发来消息说感冒了,这时你选择",
"你会选择爱还是被爱",
"最喜欢的一本书",
"每天睡眠有几小时",
"近一个星期内让你最开心的事",
"认为自己和哪种动物相似",
"最喜欢的三种食品或饮品",
"喜欢什么颜色",
"对象一口气吃了50串羊肉串,你想说什么",
"坚持最久的习惯或爱好是",
"身边异性朋友多还是同性朋友多",
"有过哪些外号",
"你如何看待爱情变成亲情",
"如何看待蓝颜",
"如何看待友情变成爱情",
"有类似‘不吃香菜’这样的忌口吗",
"大笑30秒",
"做出一个女生或男生专有的动作",
"你会做菜吗",
"今天晚上要做什么",
"用四个字形容你现在的生活状态",
"给一名异性朋友打电话说自己喝醉了",
"做一个有自己特色的动作",
"做自己最sex的表情或动作",
"对着直播深情表白3分钟",
"用三个词来形容自己",
"做一个你认为最酷的动作",
"跳一段你认为最有戏剧感的舞蹈",
"三句话让大家记住你",
"三句话让大家重新认识你",
"跪下说主人,我错了,不要赶我走",
"女反手摸肚脐,男露腹肌",
"你的口头禅是什么",
"你害怕恐怖氛围的密室逃脱吗",
"表演花手",
"假如你在街上被粉丝认出来了",
"现实生活中有社恐吗",
"喜欢用无线耳机还是有线耳机",
"做一个你认为最娘的动作",
"游戏中如果队友骂你",
"打游戏遇见了一对很菜的情侣,你会",
"说一句话证明你玩过王者荣耀",
"一句话证明你玩过英雄联盟",
"如果女朋友很坑还一定要和你打排位",
"展示三种不同的笑,各十秒",
"深情朗诵giegie",
"抬头笑,低头哭,反复三次",
"如果能重来,我要选",
"看到‘我***’你想到了什么",
"模仿猪八戒说,猴哥,师傅被妖怪抓走了",
"做三个最丑的表情并拍照留念",
"说出一名你不喜欢的同类型主播",],
next_text : ["下一题","再来一局"]
};
}
componentDidMount(){
// setTimeout( () => this.time_q(),2910);
setTimeout( () => this.time_reafy(),2900);
// setTimeout( () => this.update(),2910);
}
time_reafy()
{
this.setState({
Ready : 2, //不能放分号;
})
}
time_q()
{
this.timer = setInterval ( () => {
this.update();
},6000);
}
update(){
if(this.state.num==1){
this.setState({
num : this.state.num+1,
val : Math.floor(Math.random()*100),
})
}
else if(this.state.num==2){
this.setState({
num : this.state.num+1,
next : 1,
val : Math.floor(Math.random()*100),
})
}
else{
this.handleJump2()
}
}
ready()
{
return (
this.state.Ready <=1 &&
<View >
<Lottie
ref={this.anim}
autoPlay={true}
loop={false}
autoSize={true}
style={{
width: 350,
height: 250,
backgroundColor: "rgb(11,155,247)", //'#c7e6c8',
}}
source={require('./READY.json')}/>
</View>
)
}
pro()
{
return(
this.state.Ready >1 &&
<Text className="tip_text2">{this.state.problem[this.state.val]}</Text>
)
}
handleJump = () => {
const { history } = this.props // Router的子组件会携带history、location之类跟路由有关的对象。
history.push('/appm') // 跳转到solo页面
}
handleJump2 = () => {
const { history } = this.props // Router的子组件会携带history、location之类跟路由有关的对象。
history.push('/end') // 跳转到solo页面
}
render () {
return (
<View className="container">
<BackgroundImage
source={require('./img/background.jpg')} className="background">
<View className="title">
<Button type="primary" size="md" textColorInverse className="title_button"><Text className="title_color">真心话VS大冒险</Text></Button>
</View>
<View className="tip">
{this.ready()}
<Text className="tip_text1">{this.state.num}</Text>
{this.pro()}
</View>
<View className="next">
<Text className="next_text" onPress={() => this.update()}>{this.state.next_text[this.state.next]}</Text>
</View>
<TouchableOpacity className="type" onPress={this.handleJump}>
<Text className="type_text">返回大厅</Text>
</TouchableOpacity>
</BackgroundImage>
</View>
)
}
}
export default App
.container {
flex: 1;
}
.background{
flex: 1;
resizeMode: "cover";
justifyContent: "center";
alignItems:"center";
borderWidth: 0;
}
.title{
position:relative;
top:50;
left:40;
}
.title_button{
width: 280;
height:40;
border-radius:100px;
}
.title_color{
fontSize:25;
text-align:center;
}
.tip{
width: 350;
height:250;
backgroundColor:"rgb(82,230,252)";
position:relative;
top:80;
left:10;
text-align:center;
}
.tip_text1{
fontSize:30;
marginTop:50;
}
.tip_text2{
fontSize:20;
marginTop:20;
}
.next{
width: 200;
height:50;
alignItems: "center";
text-align:center;
backgroundColor: yellow;
position:relative;
top:120;
left:80;
border-radius:80px;
}
.next_text{
fontSize:30;
}
.type{
width: 200;
height:50;
alignItems: "center";
text-align:center;
backgroundColor: "rgb(11,155,247)";
position:relative;
top:150;
left:80;
border-radius:80px;
}
.type_text{
fontSize:30;
}
上述一个JavaScript代码一个CSS代码,当然只有这两部分代码跑不起来,他关联了其他东西,只是给你做一个参考。我说一下我认为比较重要的几个点。
定位相对定位使用方法如下图所示,绝对定位我用了一直不好使,不知道是什么情况,可能禁用?也可能是我方法不对。
下面代表在原来的基础上,向下移50,向右移40。
position:relative;
top:50;
left:40;
路径,实现按按钮弹出第二个页面
import { Route, Router } from "@hyext/router";
import { TouchableOpacity } from "react-native";
import Appm from './app'
import End from './end2'
class App extends Component {
render() {
return (
<Router initialEntries={['/main']}>
<Route path={'/main'} component={ Main }></Route>
<Route path={'/appm'} component={ Appm }></Route>
<Route path={'/end'} component={ End }></Route>
</Router>
)
}
}
handleJump = () => {
const { history } = this.props // Router的子组件会携带history、location之类跟路由有关的对象。
history.push('/appm') // 跳转到solo页面
}
handleJump2 = () => {
const { history } = this.props // Router的子组件会携带history、location之类跟路由有关的对象。
history.push('/end') // 跳转到solo页面
}
//上述是准备工作,下面是写在reader中的按钮,让它关联函数
<TouchableOpacity className="type" onPress={this.handleJump}>
<Text className="type_text">返回大厅</Text>
</TouchableOpacity>
更新数据
num : 1,
next : 0,
val : Math.floor(Math.random()*100),
update(){
if(this.state.num==1){
this.setState({
num : this.state.num+1,
val : Math.floor(Math.random()*100),
})
}
else if(this.state.num==2){
this.setState({
num : this.state.num+1,
next : 1,
val : Math.floor(Math.random()*100),
})
}
else{
this.handleJump2()
}
}
//上述是准备工作,下面是写在reader中的按钮,让它关联函数
<View className="next">
<Text className="next_text" onPress={() => this.update()}>下一题</Text>
</View>
当然要做一个好的huya小程序还有许多东西要学习,SDK,API等,我只能帮到这里了,这不是一篇具体的教学文章,更像实在告诉你该如何学习,学习重点在哪,我认为学习重点就在react-native和huya自身的一些东西,如HY-UI,SDK,API等。
我做的是一个模仿你画我猜做的真心话大冒险小游戏,如果想看全部原代码,评论即可,看到我会回复