소스 검색

Work in progress, game logic

Benoit Sida 3 년 전
부모
커밋
7afa2ecfa7

+ 2
- 0
.meteor/packages 파일 보기

@@ -20,3 +20,5 @@ shell-server@0.2.3            # Server-side component of the `meteor shell` comm
20 20
 autopublish@1.0.7             # Publish all data to the clients (for prototyping)
21 21
 insecure@1.0.7                # Allow all DB writes from clients (for prototyping)
22 22
 meyerweb-reset
23
+fourseven:scss
24
+maxharris9:classnames

+ 2
- 0
.meteor/versions 파일 보기

@@ -24,6 +24,7 @@ ecmascript-runtime@0.3.15
24 24
 ejson@1.0.13
25 25
 es5-shim@4.6.15
26 26
 fastclick@1.0.13
27
+fourseven:scss@4.5.0
27 28
 geojson-utils@1.0.10
28 29
 hot-code-push@1.0.4
29 30
 html-tools@1.0.11
@@ -35,6 +36,7 @@ jquery@1.11.10
35 36
 launch-screen@1.1.1
36 37
 livedata@1.0.18
37 38
 logging@1.1.17
39
+maxharris9:classnames@0.0.1
38 40
 meteor@1.6.1
39 41
 meteor-base@1.0.4
40 42
 meyerweb-reset@1.0.7

+ 23
- 0
imports/ui/Actions.jsx 파일 보기

@@ -0,0 +1,23 @@
1
+import React, { Component, PropTypes } from 'react';
2
+import './styles/Actions';
3
+
4
+export default class Actions extends Component {
5
+	render() {
6
+		return (
7
+			<div className="actions">
8
+				{
9
+					this.props.actions.map(action => (
10
+						<button key={action.label} onClick={action.action}>{action.label}</button>
11
+					))
12
+				}
13
+			</div>
14
+		);
15
+	}
16
+}
17
+
18
+Actions.propTypes = {
19
+	actions: PropTypes.arrayOf(PropTypes.shape({
20
+		label: PropTypes.string.isRequired,
21
+		action: PropTypes.func
22
+	})).isRequired
23
+};

+ 0
- 40
imports/ui/App.css 파일 보기

@@ -1,40 +0,0 @@
1
-#app-container {
2
-    display: flex;
3
-    min-height: 100vh;
4
-    flex-direction: column;
5
-    background: #343b59; /* Old browsers */
6
-    background: -moz-linear-gradient(top, #343b59 0%, #3f487f 100%); /* FF3.6-15 */
7
-    background: -webkit-linear-gradient(top, #343b59 0%,#3f487f 100%); /* Chrome10-25,Safari5.1-6 */
8
-    background: linear-gradient(to bottom, #343b59 0%,#3f487f 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
9
-    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#343b59', endColorstr='#3f487f',GradientType=0 ); /* IE6-9 */
10
-}
11
-
12
-#app-container #content {
13
-    flex: 1;
14
-    display: flex;
15
-    justify-content: center;
16
-}
17
-
18
-header {
19
-    height: 64px;
20
-    background: #23273c;
21
-    color: white;
22
-    line-height: 64px;
23
-    padding-left: 10px;
24
-}
25
-
26
-.test {
27
-    min-width: 50%;
28
-    width: 500px;
29
-    margin: 30px 15px;
30
-    padding: 20px;
31
-    display: flex;
32
-    flex-direction: column;
33
-}
34
-
35
-footer {
36
-    background: #23273c;
37
-    text-align: center;
38
-    color: white;
39
-    padding: 10px;
40
-}

+ 8
- 5
imports/ui/App.jsx 파일 보기

@@ -1,16 +1,19 @@
1 1
 import React, { Component } from 'react';
2
-import './App.css';
2
+import './styles/App';
3
+import Board from './Board';
3 4
 
4 5
 export default class App extends Component {
5 6
 	render() {
6 7
 		return (
7 8
 			<div id="app-container">
8
-				<header>ESPTrainer</header>
9
+				<header>-</header>
9 10
 				<main id="content">
10
-					<div className="test">
11
-						test
12
-						{/*<Board></Board>*/}
11
+					{/*<div className="left" />*/}
12
+					<div className="center">
13
+						<Board />
14
+						{/*<Actions></Actions>*/}
13 15
 					</div>
16
+					{/*<div className="right" />*/}
14 17
 				</main>
15 18
 				<footer>Copyright © 2017 Coldiary</footer>
16 19
 			</div>

+ 70
- 0
imports/ui/Board.jsx 파일 보기

@@ -0,0 +1,70 @@
1
+import React, { Component, PropTypes } from 'react';
2
+import update from 'react-addons-update';
3
+import ReactTimeout from 'react-timeout';
4
+import Square from './Square';
5
+import Trials from './Trials';
6
+import Actions from './Actions';
7
+import './styles/Board';
8
+
9
+class Board extends Component {
10
+	constructor(props) {
11
+		super(props);
12
+		this.state = {
13
+			win: false,
14
+			trials: 0,
15
+			squares: [false, false, false, false],
16
+			image: ""
17
+		};
18
+		this.actions = [
19
+			{ label: 'Reset', action: this.reset.bind(this) },
20
+			{ label: 'Pass', action: this.pass.bind(this) }
21
+		];
22
+	}
23
+
24
+	fail(corrected) {
25
+		this.setState({ squares: update(this.state.squares, { [corrected]: { $set: true } }) });
26
+		this.props.setTimeout(() => this.setState({
27
+			squares: update(this.state.squares, { [corrected]: { $set: false } })
28
+		}), 1000);
29
+	}
30
+
31
+	win() {
32
+		this.setState({ win: true });
33
+		this.props.setTimeout(() => this.setState({ win: false }), 1000);
34
+	}
35
+
36
+	choice(answer) {
37
+		let corrected = Math.floor(Math.random() * 10) % 4;
38
+		this.setState({ trials: this.state.trials + 1 });
39
+		if (answer === corrected)
40
+			this.win();
41
+		else
42
+			this.fail(corrected);
43
+	}
44
+
45
+	reset() {}
46
+
47
+	pass() {}
48
+
49
+	render() {
50
+		return (
51
+			<div className="board">
52
+				<div className="squares">
53
+					<div className="row">
54
+						<Square color="green" click={this.choice.bind(this, 0)} highlighted={this.state.squares[0]} />
55
+						<Square color="yellow" click={this.choice.bind(this, 1)} highlighted={this.state.squares[1]} />
56
+					</div>
57
+					<div className="row">
58
+						<Square color="red" click={this.choice.bind(this, 2)} highlighted={this.state.squares[2]} />
59
+						<Square color="blue" click={this.choice.bind(this, 3)} highlighted={this.state.squares[3]} />
60
+					</div>
61
+				</div>
62
+				{ this.state.win ? <Image src={this.state.image}/> : null }
63
+				<Trials count={this.state.trials} />
64
+				<Actions actions={this.actions}/>
65
+			</div>
66
+		);
67
+	}
68
+}
69
+
70
+export default ReactTimeout(Board)

+ 16
- 0
imports/ui/Image.jsx 파일 보기

@@ -0,0 +1,16 @@
1
+import React, { Component, PropTypes } from 'react';
2
+import './styles/Image';
3
+
4
+export default class Image extends Component {
5
+	render() {
6
+		return (
7
+			<div className="image">
8
+				<img src={this.props.image} alt=""/>
9
+			</div>
10
+		);
11
+	}
12
+}
13
+
14
+Image.propTypes = {
15
+	src: PropTypes.string.isRequired
16
+};

+ 18
- 0
imports/ui/Square.jsx 파일 보기

@@ -0,0 +1,18 @@
1
+import React, { Component, PropTypes } from 'react';
2
+import './styles/Square';
3
+
4
+export default class Square extends Component {
5
+	render() {
6
+		const classes = classNames('square', this.props.color, { 'highlighted': this.props.highlighted });
7
+		return (
8
+				<button className={classes} style={this.style}
9
+						onClick={this.props.click} />
10
+		);
11
+	}
12
+}
13
+
14
+Square.propTypes = {
15
+	color: PropTypes.string.isRequired,
16
+	click: PropTypes.func,
17
+	highlighted: PropTypes.bool
18
+};

+ 20
- 0
imports/ui/Trials.jsx 파일 보기

@@ -0,0 +1,20 @@
1
+import React, { Component, PropTypes } from 'react';
2
+import './styles/Trials';
3
+
4
+export default class Trials extends Component {
5
+	render() {
6
+		return (
7
+			<div className="trials">
8
+				<div><span className="number">{this.props.count}</span> <span className="text">trials</span></div>
9
+			</div>
10
+		);
11
+	}
12
+}
13
+
14
+Trials.defaultProps = {
15
+	count: 0
16
+};
17
+
18
+Trials.propTypes = {
19
+	count: PropTypes.number
20
+};

+ 25
- 0
imports/ui/styles/Actions.scss 파일 보기

@@ -0,0 +1,25 @@
1
+@import "shadow";
2
+
3
+.actions {
4
+  display: flex;
5
+  justify-content: center;
6
+  flex-wrap: wrap;
7
+  width: 300px;
8
+  margin-top: 20px;
9
+
10
+  button {
11
+    background: white;
12
+    border: 1px solid black;
13
+    @include shadow();
14
+    margin: 10px;
15
+    padding: 10px 20px;
16
+    text-transform: uppercase;
17
+    width: 100px;
18
+
19
+    &:active { box-shadow: none; }
20
+    &:focus  { outline: none; }
21
+    &:hover  { cursor: pointer; }
22
+
23
+  }
24
+
25
+}

+ 58
- 0
imports/ui/styles/App.scss 파일 보기

@@ -0,0 +1,58 @@
1
+@import 'gradient';
2
+
3
+#app-container {
4
+    display: flex;
5
+    min-height: 100vh;
6
+    flex-direction: column;
7
+    @include linear-gradient(#343b59);
8
+}
9
+
10
+main {
11
+    flex: 1;
12
+    display: flex;
13
+    justify-content: center;
14
+    flex-direction: column;
15
+}
16
+
17
+header {
18
+    height: 64px;
19
+    background: #23273c;
20
+    color: white;
21
+    line-height: 64px;
22
+    padding-left: 10px;
23
+}
24
+
25
+.left, .right {
26
+    flex: 0 0 12em;
27
+    margin: 30px;
28
+}
29
+
30
+.center {
31
+    margin: 30px;
32
+    padding: 20px;
33
+    display: flex;
34
+    flex: 1;
35
+    flex-direction: column;
36
+    background-color: rgba(0,0,0,0.1);
37
+}
38
+
39
+@media(min-width: 768px) {
40
+    .left, .right {
41
+        margin: 30px;
42
+    }
43
+
44
+    main {
45
+        flex-direction: row;
46
+    }
47
+
48
+    .center {
49
+        margin: 30px;
50
+    }
51
+}
52
+
53
+footer {
54
+    background: #23273c;
55
+    text-align: center;
56
+    color: white;
57
+    padding: 10px;
58
+}

+ 17
- 0
imports/ui/styles/Board.scss 파일 보기

@@ -0,0 +1,17 @@
1
+.board {
2
+    display: flex;
3
+    flex-direction: column;
4
+    align-items: center;
5
+
6
+    .squares {
7
+        display: flex;
8
+        flex-direction: column;
9
+
10
+        .row {
11
+            display: flex;
12
+            justify-content: center;
13
+        }
14
+    }
15
+
16
+}
17
+

+ 0
- 0
imports/ui/styles/Image.scss 파일 보기


+ 39
- 0
imports/ui/styles/Square.scss 파일 보기

@@ -0,0 +1,39 @@
1
+@import "gradient";
2
+@import "shadow";
3
+
4
+$square-blue: blue;
5
+$square-green: green;
6
+$square-red: red;
7
+$square-yellow: darken(yellow, 20);
8
+
9
+.square {
10
+    $size: 100px;
11
+
12
+    border-radius: 5px;
13
+    border: 1px solid rgba(255, 255, 255, 0.5);
14
+    height: $size;
15
+    margin: 10px;
16
+    width: $size;
17
+
18
+    @include shadow();
19
+
20
+    &:hover  { cursor: pointer; }
21
+    &:active { box-shadow: none; }
22
+    &:focus  { outline: none; }
23
+
24
+    @mixin square-color($color, $direction, $inverted) {
25
+        @if($inverted) { @include gradient(lighten($color, 20), $color, $direction); }
26
+        @else { @include gradient($color, lighten($color, 20), $direction); }
27
+        &.highlighted { @include radial-gradient($color); }
28
+    }
29
+
30
+    &.blue { @include square-color($square-blue, 'bottom', false); }
31
+    &.green { @include square-color($square-green, 'bottom', true); }
32
+    &.red { @include square-color($square-red, 'top', false); }
33
+    &.yellow { @include square-color($square-yellow, 'top', true); }
34
+
35
+}
36
+
37
+
38
+
39
+

+ 23
- 0
imports/ui/styles/Trials.scss 파일 보기

@@ -0,0 +1,23 @@
1
+.trials {
2
+    display: flex;
3
+    justify-content: center;
4
+    margin-top: 20px;
5
+
6
+    & > div {
7
+        align-items: center;
8
+        background: rgba(0,0,0,0.3);
9
+        border-radius: 5px;
10
+        color: white;
11
+        display: flex;
12
+        padding: 10px 20px;
13
+    }
14
+
15
+    & span.text {
16
+        font-size: 0.8em;
17
+        letter-spacing: 0.1em;
18
+        margin-left: 10px;
19
+        text-transform: uppercase;
20
+    }
21
+}
22
+
23
+

+ 43
- 0
imports/ui/styles/_gradient.scss 파일 보기

@@ -0,0 +1,43 @@
1
+@mixin gradient($one, $two, $direction) {
2
+  $deg: if($direction == 'top', 45deg, -45deg);
3
+  $word: if($direction == 'top', bottom, top);
4
+  $opposite: if($direction == 'top', top, bottom);
5
+  background: $one;
6
+  background: -moz-linear-gradient($deg, $one 0%, $two 100%);
7
+  background: -webkit-gradient(left $word, right $opposite, color-stop(0%, $one), color-stop(100%, $two));
8
+  background: -webkit-linear-gradient($deg, $one 0%, $two 100%);
9
+  background: -o-linear-gradient($deg, $one 0%, $two 100%);
10
+  background: -ms-linear-gradient($deg, $one 0%, $two 100%);
11
+  background: linear-gradient($deg, $one 0%, $two 100%);
12
+  filter: progid:DXImageTransform.Microsoft.gradient(
13
+                  startColorstr='#{ie_hex_str($one)}',
14
+                  endColorstr='#{ie_hex_str($two)}',
15
+                  GradientType=1
16
+  );
17
+}
18
+
19
+@mixin linear-gradient($color) {
20
+  $lighten: lighten($color, 10);
21
+  background: $color;
22
+  background: -moz-linear-gradient(top, $color 0%, $lighten 100%);
23
+  background: -webkit-linear-gradient(top, $color 0%, $lighten 100%);
24
+  background: linear-gradient(to bottom, $color 0%, $lighten 100%);
25
+  filter: progid:DXImageTransform.Microsoft.gradient(
26
+                  startColorstr='#{ie_hex_str($color)}',
27
+                  endColorstr='#{ie_hex_str($lighten)}',
28
+                  GradientType=0
29
+  );
30
+}
31
+
32
+
33
+@mixin radial-gradient($color) {
34
+  $lighten: lighten($color, 35);
35
+  background: $lighten;
36
+  background: -moz-radial-gradient(center, ellipse cover, $lighten 0%, $color 100%);
37
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, $lighten), color-stop(100%, $color));
38
+  background: -webkit-radial-gradient(center, ellipse cover, $lighten 0%, $color 100%);
39
+  background: -o-radial-gradient(center, ellipse cover, $lighten 0%, $color 100%);
40
+  background: -ms-radial-gradient(center, ellipse cover, $lighten 0%, $color 100%);
41
+  background: radial-gradient(ellipse at center, $lighten 0%, $color 100%);
42
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#{ie_hex_str($lighten)}', endColorstr='#{ie_hex_str($color)}', GradientType=1 );
43
+}

+ 3
- 0
imports/ui/styles/_shadow.scss 파일 보기

@@ -0,0 +1,3 @@
1
+@mixin shadow() {
2
+  box-shadow: 0 2px 5px 1px rgba(0,0,0,0.5);
3
+}

+ 3
- 1
package.json 파일 보기

@@ -8,6 +8,8 @@
8 8
     "babel-runtime": "^6.20.0",
9 9
     "meteor-node-stubs": "~0.2.4",
10 10
     "react": "^15.4.2",
11
-    "react-dom": "^15.4.2"
11
+    "react-addons-update": "^15.4.2",
12
+    "react-dom": "^15.4.2",
13
+    "react-timeout": "^1.0.0"
12 14
   }
13 15
 }