我希望在游戏的AI移动(startThinking功能)时禁用onClick,这样玩家就不会随意点击游戏的任何部分并搞砸了。
这是我的类的代码,我想从中访问变量onclick和cursor(由** **包围的相关位):
class Grid extends React.Component{
constructor(props){
super(props);
var pos = props.pos;
this.xPos = 2+(pos%9)*66+"px";
this.yPos = 2+(Math.floor(pos/9))*66+"px";
this.borderTop = "none";
this.borderLeft = "none";
this.borderRight = "none";
this.borderBottom = "none";
if(pos%3==0){
this.borderLeft = "solid";
}
if(pos%9==8){
this.borderRight = "solid";
}
if(pos>71){
this.borderBottom = "solid";
}
if((pos%27)<9){
this.borderTop = "solid";
}
}
render(){
var pos = this.props.pos;
var icon = this.props.icon;
var backgroundColor = (icon==="none")?((!this.props.legal)?((pos%2)?"white":"#f2f2f2"):((pos%2)?"rgb(177, 251, 169)":"rgb(157, 228, 150)")):((icon==="x")?"rgb(243, 125, 125)":"#6f83f3");
var choice = "";
var **onclick** = (this.props.legal)?this.props.onclick:(()=>{});
var **cursor** = (this.props.legal)?"pointer":"default";
if(icon !== "none"){
choice = (<div className='icon'>{icon}</div>);
}
return(<div onClick={onclick} style={{cursor:cursor,backgroundColor:backgroundColor,top:this.yPos,left:this.xPos,borderLeft:this.borderLeft,borderRight:this.borderRight,borderTop:this.borderTop,borderBottom:this.borderBottom}} className='grid' >{choice}</div>);
}
}
这是我要从中访问变量onclick和cursor的类,并在gameAI开始思考之前将它们更改为默认值(即未激活),然后我想在gameAI结束后将它们恢复为原始状态思考并采取了行动。相关位包围** **
class Board extends React.Component {
constructor(props){
super(props);
this.state = {
model: curGame
}
setSimBoard(this);
}
render() {
var model = this.state.model;
var i = -1;
var comps = model.grid.map((sq)=>{
i++;
var n = "block_"+i;
var leg = model.legals.indexOf(i)>-1;
return <Grid id={n} key={n} pos={i} icon={sq.icon} legal={leg} onclick={
((i)=>{
** return ()=>{
// the comments are what i tried, didn't work Grid.onclick = (()=>{});
// Grid.cursor = "default";
startThinking(i);
model.makeMove(i);
// Grid.onclick = (this.props.legal)?this.props.onclick:(()=>{});
// Grid.cursor = (this.props.legal)?"pointer":"default";
this.setState({model:model});
}
})(i) **
}/>;
});
return (
<div>
<div>{comps}</div>
<BoardStatus model={model}/>
<WinCover model={model}/>
</div>
);
}
}
最后,这里是startThinking函数,它位于另一个js文件中。评论是我试过的。 ai属于另一个文件,它是gameAI,而它正在进行计算以进行移动。
function startThinking(i){
//document.getElementById('id').style.pointerEvents = 'none';
console.log("thinking..");
ai.postMessage({game:Object.assign({"ai":true}, curGame) ,move:i});
// document.getElementById('id').style.pointerEvents = 'auto';
}
我真的很感激这方面的帮助!非常感谢你!
编辑:所以,Pranesh Ravi告诉我如何从另一个类的类中访问变量。但是,由于这并没有解决我的问题,我想知道如何从另一个文件ai.js访问onclick和游标变量,其相关部分如下所示,以及超级相关部分被** **包围。注释是我试图在gameAI工作时禁用click的,这给了我一个参考错误,说明没有定义Board是有意义的。
var thinkTime = 2000;
var think = false;
var maxDepth = 6;
onmessage = function(msg){
** // Board.onclick = (()=>{});
// Board.cursor = "default" **
var game = msg.data.game;
var playerMove = msg.data.move;
think = true;
var search = new SearchTree(game,playerMove,0);
var bestMove = search.traverse(maxDepth,true);
console.log(bestMove);
postMessage(bestMove.move);
** // Board.onclick = (this.props.legal)?this.props.onclick:(()=>{});
// Board.cursor = (this.props.legal)?"pointer":"default"; **
}
答案 0 :(得分:1)
像Redux这样的库解决了这个问题。
您有一个中央存储库,其中包含游戏状态的信息。我给你两种解决方法。
选项1.获取Grid组件的ref并调用一个返回所需信息的函数。
选项2.由于获取组件的引用是不好的做法,因此更纯粹的方法是在呈现时将函数传递给子组件。用于注册获取所需信息的函数。这是我推荐的方法。
class Board extends Component {
constructor(props) {
super(props);
this.registerStateFetcher = this.registerStateFetcher.bind(this);
}
registerStateFetcher(fetcher) {
this.stateFetcher = fetcher;
}
render() {
return <Grid registerStateFetcher={ this.registerStateFetcher } />
}
}
class Grid extends Component {
constructor(props) {
super(props);
props.registerStateFetcher(this.getGameState.bind(this));
}
getGameState() {
// recollect info needed and return
return {};
}
}
答案 1 :(得分:0)
在您的项目中,Board
可以从Grid
而不是React.Component
延伸。并在super
的{{1}}内拨打constructor
。 Board
将运行其父类的super
。因此,constructor
内的所有this
现在都可以在Grid
中使用。添加了一个简单的例子来证明这一点。
希望这有帮助!
Board
&#13;
class Grid extends React.Component{
constructor(props){
super(props)
this.onClick = 'This is a onclick variable'
this.cursor = 'This is cursor'
}
render(){
return <h1>Render from Component Grid</h1>
}
}
class Board extends Grid{ //extending Grid
constructor(props){
super(props) //calling super to run the constructor of Grid
}
render(){
console.log(this.onClick) //Accessing onClick from Grid
console.log(this.cursor) //Accessing cursor from Grid
return <h1>Render from Component Board</h1>
}
}
ReactDOM.render(
<div>
<Grid/>
<Board/>
</div>
, document.getElementById('app')
)
&#13;