我已经通过同样的问题浏览了许多其他主题,但似乎没有人能找到我正在寻找的解决方案。我按照了YouTube的教程(Fullstack Development是频道,它是如何在28分钟内制作游戏)。我的主要代码如下:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Dimensions,
Animated,
Image,
} from 'react-native';
import Enemy from './app/components/Enemy';
export default class Blox extends Component {
constructor(props){
super(props);
this.state = {
movePlayerVal: new Animated.Value(40),
playerSide:'left',
points: 0,
moveEnemyVal: new Animated.Value(0),
enemyStartposX: 0,
enemySide: 'left',
enemySpeed: 4200,
gameOver: false,
};
}
render() {
return (
<Image source = {require('./app/img/bg.png')} style={styles.container}>
<View style= {{ flex:1, alignItems: 'center', marginTop: 80 }}>
<View style={styles.points}>
<Text style={{ fontWeight: 'bold', fontSize: 40 }}>{this.state.points}</Text>
</View>
</View>
<Animated.Image source={require('./app/img/car.png')}
style = {{
height:100,
width:100,
position:'absolute',
zIndex:1,
bottom: 50,
resizeMode: 'stretch',
transform: [
{ translateX: this.state.movePlayerVal }
]
}}></Animated.Image>
<Enemy enemyImg={require('./app/img/enemy.png')}
enemyStartposX={this.state.enemyStartposX}
moveEnemyVal={this.state.moveEnemyVal} />
<View style={styles.controls}>
<Text style = {styles.left} onPress={ () => this.movePlayer('left') }> {'<'} </Text>
<Text style={styles.right} onPress={ () => this.movePlayer('right') }> {'>'} </Text>
</View>
</Image>
);
}
movePlayer(direction) {
//move player right
if (direction == 'right') {
this.setState({ playerSide: 'right' }); //issue with setState being used as a function (from lines 78-124)
Animated.spring(
this.state.movePlayerVal,
{
toValue: Dimensions.get('window').width = 140,
tension: 120,
}
).start();
} else if (direction == 'left') {
this.setState({ playerSide: 'left' });
Animated.spring(
this.state.movePlayerVal,
{
toValue: 40,
tension: 120,
}
).start();
}
}
componentDidMount() {
this.animateEnemy();
}
animateEnemy() {
this.state.moveEnemyVal.setValue(-100);
var windowH = Dimensions.get('window').height;
//Generate left distance for enemy
var r = Math.floor(Math.random() * 2) * 1;
if (r == 2) {
r = 40;
this.setState({ enemySide: 'left' });
} else {
r = Dimensions.get('window').width = 140;
//Enemy is on the right
this.setState = ({ enemySide: 'right' });
}
this.setState({ enemyStartposX: r }); //issue with this
//Interval to check for collision each 50 ms
var refreshIntervalId;
refreshIntervalId = ( () => {
//Collision logic
//If enemy collides with player and they are on the same side
//and the enemy has not passed the player safely
if (this.state.moveEnemyVal._value > windowH - 280 && this.state.moveEnemyVal._value < windowH -180 && this.state.playerSide == this.state.enemySide) {
clearInterval(refreshIntervalId)
this.setState({ gameOver: true });
this.gameOver();
}
}, 50);
//Increase enemy speed each 20th second
setInterval ( () => {
this.setState({ enemySpeed: this.state.enemySpeed - 50 })
}, 20000);
//Animate the enemy
Animated.timing(
this.state.moveEnemyVal,
{
toValue: Dimensions.get('window').height,
duration: this.state.enemySpeed,
}
).start(event => {
//if no enemy collision is detected, restart enemy animation
if (event.finished && this.state.gameOver == false) {
clearInterval(refreshIntervalId);
this.setState({ points: ++this.state.points });
this.animateEnemy();
}
});
}
gameOver() {
alert('You lost big time!');
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
position: 'relative',
resizeMode: 'cover',
},
points: {
width: 80,
height: 80,
backgroundColor: '#fff',
borderRadius: 100,
alignItems: 'center',
justifyContent: 'center',
},
controls: {
alignItems: 'center',
flexDirection: 'row',
},
right: {
flex: 1,
color: '#fff',
margin: 0,
fontSize: 60,
fontWeight: 'bold',
textAlign: 'left'
},
left: {
flex: 1,
color: '#fff',
fontSize: 60,
fontWeight: 'bold',
textAlign: 'right'
},
});
我还有一个看起来像这样的敌人类:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Animated,
Image,
} from 'react-native';
export default class Enemy extends Component {
render() {
return (
<Animated.Image source={this.props.enemyImg}
style = {{
height:100,
width:100,
position:'absolute',
resizeMode: 'stretch',
left: this.props.enemyStartposX,
transform: [
{ translateY: this.props.moveEnemyVal },
]
}}></Animated.Image>
);
}
}
我通过XDE世博会运行这个,当我构建它时,它起作用了。然而,一旦我开始编码动画,世博会变红了,说我在第124行(在App.js中)有一个错误,.setState不是一个函数,它是一个对象。我评论了它,它告诉我在我的App.js文件的第78行中有同样的错误。你能告诉我.setState是什么,以及如何解决这个错误?感谢。
答案 0 :(得分:0)
您应该将movePlayer
函数绑定到构造函数中的适当范围:
constructor() {
this.movePlayer = this.movePlayer.bind(this);
}
答案 1 :(得分:0)
我认为您的问题是如何处理方法回调。您只需在构造函数中bind
方法movePlayer()
和animateEnemy()
,如:
constructor(props) {
super(props);
this.state = {
movePlayerVal: new Animated.Value(40),
playerSide:'left',
points: 0,
moveEnemyVal: new Animated.Value(0),
enemyStartposX: 0,
enemySide: 'left',
enemySpeed: 4200,
gameOver: false,
};
// This binding is necessary to make `this` work in the callback
this.movePlayer = this.movePlayer.bind(this);
this.animateEnemy = this.animateEnemy.bind(this);
}
也许你可以在this中的ReactNative中深入了解你的句柄方法。
我希望我的回答可以帮到你..
答案 2 :(得分:0)
您的animateEnemy
函数中的setState调用错误。这就是你收到错误信息的原因。
animateEnemy() {
...
if (r == 2) {
r = 40;
this.setState({ enemySide: 'left' });
} else {
r = Dimensions.get('window').width = 140;
// Enemy is on the right
// this.setState = ({ enemySide: 'right' }); // This is wrong
this.setState({ enemySide: 'right' });
}
...
}
如果用箭头函数animateEnemy = () => { ... }
更改所有函数会更好。通过这种方式,您无需在构造函数中手动绑定它。