diff --git a/README.md b/README.md index 00e6cef..df2cc9f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # React & Redux based Hearthstone clone -Built for educational purposes only. Your contributions are welcome. +Built for educational purposes only. Your contributions are welcome 😉 -## [PLAY DEMO](https://zergetaev.ru/typescript-redux-card-game/) +### [PLAY DEMO](https://zergetaev.ru/typescript-redux-card-game/) ## Roadmap: @@ -10,18 +10,31 @@ Built for educational purposes only. Your contributions are welcome. * [x] Armor * [x] HP * [x] Mana -* [x] Battlefield -* [x] Hand -* [x] Deck -* [ ] Turns + * [ ] Overload +* [x] Entities + * [x] Player + * [x] Hero + * [x] Minion + * [x] Weapon + * [ ] Hero power + * [ ] Spell + * [ ] Secret + * [ ] Quest + * [ ] Sidequest +* [x] Zones + * [x] Play + * [x] Hand + * [x] Deck + * [ ] Graveyard + * [ ] Set aside + * [ ] Secret + * [ ] Removed from game +* [x] Turns * [x] Player control switch - * [ ] Turn timer - (https://github.com/matpaul/redux-timer-middleware, https://stackoverflow.com/questions/3969475/javascript-pause-settimeout) * [x] Fatigue damage * [x] Card overdraw damage -* [x] Weapons -* [x] Minions -* [x] Heroes + * [ ] 🕡 Turn timer + (https://github.com/matpaul/redux-timer-middleware, https://stackoverflow.com/questions/3969475/javascript-pause-settimeout) * [x] Basic mechanics * [x] Charge * [x] Windfury @@ -30,23 +43,28 @@ Built for educational purposes only. Your contributions are welcome. * [ ] Stealth (needs targeting improvements) * [ ] Poisonous * [ ] Divine shield -* [ ] Graveyard -* [ ] Spells - * [ ] Secrets -* [ ] Hero powers -* [ ] Triggers +* [ ] Card targeting requirements + +### Visual +* [x] Card rendering (basic) + * [ ] Use [Sunwell](https://github.com/HearthSim/Sunwell)? +* [x] Drag & Drop cards(react-dnd) + * [x] Touch screens support +* [ ] Fix minion death animation bug (#10) + +### Technical +* [ ] Merge all game entities into `game.entities` (?) +* [ ] Tests + * [ ] [Sequences](https://hearthstone.gamepedia.com/Advanced_rulebook#Advanced_mechanics_101_.28READ_THIS_FIRST.29) (will require major refactoring) * [ ] Load cards from https://hearthstonejson.com/ * [ ] Save/Load * [ ] LocalStorage * [ ] File system * [ ] ~~Multiplayer~~ +* [ ] Triggers -### Visual -* [x] Card rendering (basic) - * [ ] Use [Sunwell](https://github.com/HearthSim/Sunwell)? -* [x] Drag & Drop cards +## Development + $ yarn && yarn start -## Technical -* [ ] Merge game entities? -* [ ] Tests +Open `localhost:3000` in your web browser :tada: diff --git a/package.json b/package.json index 62b1206..c21e52a 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "react": "^16.12.0", "react-dnd": "^10.0.2", "react-dnd-html5-backend": "^10.0.2", + "react-dnd-touch-backend": "^10.0.2", "react-dom": "^16.12.0", "react-hs-components": "https://libs.hearthsim.net/react-hs-components-v0.3.0.tgz", "react-redux": "^7.1.3", diff --git a/src/UI/App.tsx b/src/UI/App.tsx index ef1e992..0fd64f4 100644 --- a/src/UI/App.tsx +++ b/src/UI/App.tsx @@ -1,6 +1,7 @@ import React from "react"; import { DndProvider } from "react-dnd"; import HTML5Backend from "react-dnd-html5-backend"; +import TouchBackend from "react-dnd-touch-backend"; import { Container, Grid, @@ -9,10 +10,13 @@ import { GridColumn } from "semantic-ui-react"; import TargetableBattlefield from "./Play/Battlefield"; -import * as Toastr from "toastr"; +import Toastr from "toastr"; import "toastr/build/toastr.css"; +import { isTouch } from "./utils"; -Toastr.options.timeOut = 3000; //Change the settings +Toastr.options.timeOut = 3000; + +const DnDBackend = isTouch() ? TouchBackend : HTML5Backend; const App: React.FC = props => ( @@ -29,7 +33,7 @@ const App: React.FC = props => ( - + diff --git a/src/UI/Play/DnDMinion.tsx b/src/UI/Play/DnDMinion.tsx index 8a6f776..56537f1 100644 --- a/src/UI/Play/DnDMinion.tsx +++ b/src/UI/Play/DnDMinion.tsx @@ -49,7 +49,8 @@ const DnDMinion: React.FC = ({ character }) => { }); const [{ canDrag }, dragRef] = useDrag({ item: character, - canDrag: monitor => character.owner === state.activePlayer && canAttack(character), + canDrag: monitor => + character.owner === state.activePlayer && canAttack(character), collect: monitor => ({ canDrag: monitor.canDrag() }) diff --git a/src/UI/utils.ts b/src/UI/utils.ts new file mode 100644 index 0000000..7bcd048 --- /dev/null +++ b/src/UI/utils.ts @@ -0,0 +1,2 @@ +export const isTouch = () => + "ontouchstart" in window || navigator.msMaxTouchPoints > 0; diff --git a/src/redux/modules/gameStateReducer.ts b/src/redux/modules/gameStateReducer.ts index 6a05b98..b798a1f 100644 --- a/src/redux/modules/gameStateReducer.ts +++ b/src/redux/modules/gameStateReducer.ts @@ -13,7 +13,12 @@ import { Step } from "../../models"; import { burnCard, drawCard } from "./deckReducer"; -import { fatigueDamage, gainMana, processDeaths, restoreMana } from "./play/actions"; +import { + fatigueDamage, + gainMana, + processDeaths, + restoreMana +} from "./play/actions"; import initialState from "./initialState"; import Toastr from "toastr"; diff --git a/yarn.lock b/yarn.lock index f04e57c..3f78688 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9810,6 +9810,14 @@ react-dnd-html5-backend@^10.0.2: dependencies: dnd-core "^10.0.2" +react-dnd-touch-backend@^10.0.2: + version "10.0.2" + resolved "https://registry.yarnpkg.com/react-dnd-touch-backend/-/react-dnd-touch-backend-10.0.2.tgz#90cb916655539b838d49b8895e1813f8b874b3b4" + integrity sha512-+lW/Ern0dKyHToD0oP+Wc/ZD6l7qJazosLqbjzL7OnPlig6WxdlrHkJylOLkeAdZj41fIJJ551Lb57pIL0CcPw== + dependencies: + "@react-dnd/invariant" "^2.0.0" + dnd-core "^10.0.2" + react-dnd@^10.0.2: version "10.0.2" resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-10.0.2.tgz#a6ad8eb3d9f2c573031f7ce05012e5c767a0b1fc"