1
1
import React , { Component } from 'react' ;
2
- import { View ,
3
- Text ,
4
- StyleSheet ,
5
- Dimensions ,
6
- Image } from 'react-native' ;
2
+ import { View , Text , StyleSheet , Dimensions , Image , Modal , TouchableOpacity , TouchableWithoutFeedback } from 'react-native' ;
3
+ import * as Haptics from 'expo-haptics' ;
7
4
import Score from './components/Score' ;
8
5
import Emoji from './components/Emoji' ;
6
+ import * as All from './images' ;
9
7
10
8
const LC_IDLE = 0 ;
11
9
const LC_RUNNING = 1 ;
12
10
const LC_TAPPED = 2 ;
13
- const GRAVITY = 0.8 ;
11
+ const GRAVITY = 0.6 ;
14
12
const TAPPED_VELOCITY = 20 ;
15
13
const ROTATION_FACTOR = 7 ;
16
-
17
14
const SCREEN_HEIGHT = Dimensions . get ( 'window' ) . height ;
18
15
const SCREEN_WIDTH = Dimensions . get ( 'window' ) . width ;
19
16
const BALL_WIDTH = SCREEN_WIDTH * 0.33 ;
@@ -22,9 +19,17 @@ const FLOOR_Y = SCREEN_HEIGHT - BALL_HEIGHT;
22
19
const FLOOR_X = SCREEN_WIDTH / 2 ;
23
20
const SCORE_Y = SCREEN_HEIGHT / 6 ;
24
21
const EMOJI_Y = SCREEN_HEIGHT / 3 ;
22
+ const sports = [ 'soccer' , 'baseball' , 'basketball' , 'football' , 'golf' , 'tennis' , 'hockey' ]
23
+
24
+ function Sports ( { sport, set} ) {
25
+ return (
26
+ < TouchableOpacity onPress = { ( ) => set ( sport ) } >
27
+ < Image style = { { width : Dimensions . get ( 'window' ) . width * 0.3 , height : Dimensions . get ( 'window' ) . width * 0.3 , marginBottom : 15 } } source = { All [ `${ sport } ` ] } />
28
+ </ TouchableOpacity >
29
+ )
30
+ }
25
31
26
32
class Soccer extends Component {
27
-
28
33
constructor ( props ) {
29
34
super ( props ) ;
30
35
this . interval = null ;
@@ -38,6 +43,9 @@ class Soccer extends Component {
38
43
scored : false ,
39
44
lost : false ,
40
45
rotate : 0 ,
46
+ sport : All . soccer ,
47
+ visible : true ,
48
+ button : true
41
49
} ;
42
50
}
43
51
@@ -52,6 +60,8 @@ class Soccer extends Component {
52
60
}
53
61
54
62
onTap ( event ) {
63
+ Haptics . selectionAsync ( )
64
+ this . setState ( { button : false } )
55
65
if ( this . state . lifeCycle === LC_TAPPED ) {
56
66
this . setState ( {
57
67
lifeCycle : LC_RUNNING ,
@@ -61,8 +71,7 @@ class Soccer extends Component {
61
71
else {
62
72
let centerX = BALL_WIDTH / 2 ;
63
73
let centerY = BALL_HEIGHT / 2 ;
64
- let velocityX = ( ( centerX - event . locationX ) / SCREEN_WIDTH )
65
- * TAPPED_VELOCITY ;
74
+ let velocityX = ( ( centerX - event . locationX ) / SCREEN_WIDTH ) * TAPPED_VELOCITY ;
66
75
let velocityY = - TAPPED_VELOCITY ;
67
76
this . setState ( {
68
77
vx : velocityX ,
@@ -82,18 +91,19 @@ class Soccer extends Component {
82
91
nextState . rotate += ROTATION_FACTOR * nextState . vx ;
83
92
// Hit the left wall
84
93
if ( nextState . x < BALL_WIDTH / 2 ) {
94
+ Haptics . selectionAsync ( )
85
95
nextState . vx = - nextState . vx ;
86
96
nextState . x = BALL_WIDTH / 2 ;
87
97
}
88
-
89
98
// Hit the right wall
90
99
if ( nextState . x > SCREEN_WIDTH - BALL_WIDTH / 2 ) {
100
+ Haptics . selectionAsync ( )
91
101
nextState . vx = - nextState . vx ;
92
102
nextState . x = SCREEN_WIDTH - BALL_WIDTH / 2 ;
93
103
}
94
-
95
104
// Reset after falling down
96
105
if ( nextState . y > SCREEN_HEIGHT + BALL_HEIGHT ) {
106
+ Haptics . selectionAsync ( )
97
107
nextState . y = FLOOR_Y ;
98
108
nextState . x = FLOOR_X ;
99
109
nextState . lifeCycle = LC_IDLE ;
@@ -109,17 +119,20 @@ class Soccer extends Component {
109
119
110
120
update ( ) {
111
121
if ( this . state . lifeCycle === LC_IDLE ) {
122
+ this . setState ( { button : true } )
112
123
return ;
113
124
}
114
-
115
125
let nextState = Object . assign ( { } , this . state ) ;
116
-
117
126
this . updatePosition ( nextState ) ;
118
127
this . updateVelocity ( nextState ) ;
119
-
120
128
this . setState ( nextState ) ;
121
129
}
122
130
131
+ setSport ( sport ) {
132
+ Haptics . selectionAsync ( )
133
+ this . setState ( { visible : false , sport : All [ `${ sport } ` ] } )
134
+ }
135
+
123
136
render ( ) {
124
137
var position = {
125
138
left : this . state . x - ( BALL_WIDTH / 2 ) ,
@@ -134,10 +147,32 @@ class Soccer extends Component {
134
147
< View >
135
148
< Score score = { this . state . score } y = { SCORE_Y } scored = { this . state . scored } />
136
149
< Emoji scored = { this . state . scored } y = { EMOJI_Y } lost = { this . state . lost } />
137
- < Image source = { require ( './images/soccer.png' ) }
138
- style = { [ styles . ball , position , rotation ] }
139
- onStartShouldSetResponder = { ( event ) => this . onTap ( event . nativeEvent ) }
140
- />
150
+ < TouchableWithoutFeedback style = { { padding : 20 } }
151
+ onPress = { ( event ) => this . onTap ( event . nativeEvent ) }
152
+ onPressIn = { ( event ) => this . onTap ( event . nativeEvent ) }
153
+ onPressOut = { ( event ) => this . onTap ( event . nativeEvent ) } >
154
+ < Image source = { this . state . sport } style = { [ styles . ball , position , rotation ] } />
155
+ </ TouchableWithoutFeedback >
156
+ < Modal animationType = 'slide' presentationStyle = 'formSheet' visible = { this . state . visible } >
157
+ < View style = { { alignItems : "center" , marginTop : Dimensions . get ( 'window' ) . height * 0.2 } } >
158
+ < Text style = { { fontSize : "40" , fontWeight : "200" , marginBottom : 20 } } >
159
+ Choose your sport
160
+ </ Text >
161
+ < View style = { { flexDirection : "row" , flexWrap : "wrap" , justifyContent :"space-evenly" } } >
162
+ { sports . map ( sport => { return < Sports key = { sport } set = { ( ) => this . setSport ( sport ) } sport = { sport } /> } ) }
163
+ </ View >
164
+ </ View >
165
+ </ Modal >
166
+ { this . state . button == true && < TouchableOpacity onPressIn = { ( ) => { this . setState ( { visible : true } ) , Haptics . selectionAsync ( ) } }
167
+ style = { { padding : 10 , height : 55 , width : 55 , position : 'absolute' , bottom : 30 , right : 30 , borderColor : '#e7e7e6' , borderWidth : 0.5 , shadowColor : "#555a74" ,
168
+ shadowOffset : { height : 0.5 , width : 0.5 } ,
169
+ shadowOpacity : 0.5 ,
170
+ shadowRadius : 0.5 ,
171
+ backgroundColor : "white" ,
172
+ borderRadius : 5 ,
173
+ elevation : 8 ,
174
+ justifyContent : 'center' ,
175
+ alignItems : 'center' } } > < Image style = { { height : 50 , width : 50 } } source = { require ( './images/sportballs.png' ) } /> </ TouchableOpacity > }
141
176
</ View >
142
177
) ;
143
178
}
0 commit comments