diff --git a/README.md b/README.md index 0e7e01df..8e895426 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,162 @@ -

- -

-

Vscode Live Server++ (BETA)

-

It's Truly Live

- - -[![VSCode Marketplace](https://img.shields.io/vscode-marketplace/v/ritwickdey.vscode-live-server-plus-plus.svg?style=flat-square&label=vscode%20marketplace)](https://marketplace.visualstudio.com/items?itemName=ritwickdey.vscode-live-server-plus-plus) [![Total Installs](https://img.shields.io/vscode-marketplace/d/ritwickdey.vscode-live-server-plus-plus.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=ritwickdey.vscode-live-server-plus-plus) [![Avarage Rating](https://img.shields.io/vscode-marketplace/r/ritwickdey.vscode-live-server-plus-plus.svg?style=flat-square)](https://marketplace.visualstudio.com/items?itemName=ritwickdey.vscode-live-server-plus-plus) [![Travis branch](https://img.shields.io/travis/com/ritwickdey/vscode-live-server-plus-plus/master.svg?style=flat-square&label=travis%20branch)](https://travis-ci.com/ritwickdey/vscode-live-server-plus-plus) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/ritwickdey/vscode-live-server-plus-plus/) - ---- - -![VSCode Live Server++](./images/vscode-live-server-plus-plus_preview1.gif) - ---- -## Features - -- **No Need to save HTML, CSS, JS** :smile: -- **No Browser full reload** (for HTML & CSS) -- Customizable Server Root -- Customizable Server Port -- Customizable reloading time -- Customizable index file (e.g `index.html`) -- Auto Browser open (Mozila, Chrome & Edge) -- Control from statusbar - ---- - -## Downside - -- `Live Server++` will work well if your project only contents `css` & `html` and minimal `JavaScript`. If you do lot of DOM Manupulation with JavaScript, `Live Server++` is not recommended. - ---- -## How to Start/Stop Server ? - -1. Open a project and click to `Go Live++` from the status bar to turn the server on/off. - -2. Open the Command Pallete by pressing `F1` or `ctrl+shift+P` and type `Live Server++: Open Server` to start a server or type `Live Server++: Close Server` to stop a server. - ---- - -## Settings - -[Click here to read settings Docs](./docs/settings.md). - -## What's new ? - -- ### v0.0.1 (##DATE##) - - Initial release - - hot Reload supported - - No need to save - - 5 settings are added (Port, Root, indexFile, timeout, browser) - ---- - -## Changelog - -To check full changelog [click here](CHANGELOG.md). - ---- - -## Why `Live Server++` when there is a `Live Server` ? - -Actually, I was receiving a lot of emails, PR, comments (and also there was few issue request, e.g. [#12080](https://github.com/Microsoft/vscode/issues/12080)) - `why auto reload only happens when we save the file`? - `why it's not realtime?`... blah blah.... - -Well, in Live Server Extension, I'm using a popular npm module (named `live-server`) and it's the core library of Live Server. _(yaa! too many "Live Server" 😜)_. In the way it's working - it never possible auto reload without saving the file. - -And yaa, to be honest, when I made (in mid of `2017`) the live server extension, I didn't know Node.js or JavaScript well _(Hold on! I still don't know `Node.js` but I'm now confident)_. I even didn't know `promise`/`callback` well. I understood the `callback` _(& `callback hell` too)_ while making the extension. And `Promise`? Only I knew how to use it like `.then().then().then()` and `IIFE`? or `closure`? - I didn't even hear about those names at that time. 😬 - -Okay, now coming to the point, Code of the `Live Server` can't be migrated with `Live Server++`. `Live Server++` is not depended on `live-server`(the npm module) - I've written the server side code from scratch & it has minimal dependency (still under development). - ---- - -## LICENSE - -This extension is licensed under the [MIT License](LICENSE) + import 'dart:async'; +import 'dart:math'; +import 'package:flutter/material.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Snake Game', + home: SnakeGame(), + debugShowCheckedModeBanner: false, + ); + } +} + +class SnakeGame extends StatefulWidget { + @override + _SnakeGameState createState() => _SnakeGameState(); +} + +class _SnakeGameState extends State { + static const int rowCount = 20; + static const int columnCount = 20; + final random = Random(); + + List> snake = [Point(10, 10)]; + Point food = Point(5, 5); + String direction = 'up'; + Timer? timer; + + @override + void initState() { + super.initState(); + startGame(); + } + + void startGame() { + timer = Timer.periodic(Duration(milliseconds: 200), (_) { + setState(() { + moveSnake(); + if (snake.first == food) { + snake.add(snake.last); + food = Point(random.nextInt(columnCount), random.nextInt(rowCount)); + } + checkGameOver(); + }); + }); + } + + void moveSnake() { + final head = snake.first; + Point newHead; + + switch (direction) { + case 'up': + newHead = Point(head.x, head.y - 1); + break; + case 'down': + newHead = Point(head.x, head.y + 1); + break; + case 'left': + newHead = Point(head.x - 1, head.y); + break; + case 'right': + newHead = Point(head.x + 1, head.y); + break; + default: + return; + } + + snake.insert(0, newHead); + snake.removeLast(); + } + + void checkGameOver() { + final head = snake.first; + if (head.x < 0 || head.y < 0 || head.x >= columnCount || head.y >= rowCount || snake.skip(1).contains(head)) { + timer?.cancel(); + showDialog( + context: context, + builder: (_) => AlertDialog( + title: Text('Game Over'), + content: Text('You lost!'), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + resetGame(); + }, + child: Text('Restart'), + ), + ], + ), + ); + } + } + + void resetGame() { + setState(() { + snake = [Point(10, 10)]; + food = Point(5, 5); + direction = 'up'; + startGame(); + }); + } + + void changeDirection(String newDirection) { + if ((direction == 'up' && newDirection != 'down') || + (direction == 'down' && newDirection != 'up') || + (direction == 'left' && newDirection != 'right') || + (direction == 'right' && newDirection != 'left')) { + direction = newDirection; + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: GestureDetector( + onVerticalDragUpdate: (details) { + if (details.primaryDelta! < 0) changeDirection('up'); + else if (details.primaryDelta! > 0) changeDirection('down'); + }, + onHorizontalDragUpdate: (details) { + if (details.primaryDelta! < 0) changeDirection('left'); + else if (details.primaryDelta! > 0) changeDirection('right'); + }, + child: GridView.builder( + itemCount: rowCount * columnCount, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: columnCount, + ), + itemBuilder: (context, index) { + final x = index % columnCount; + final y = index ~/ columnCount; + final point = Point(x, y); + + Color color; + if (snake.contains(point)) { + color = Colors.green; + } else if (point == food) { + color = Colors.red; + } else { + color = Colors.grey.shade900; + } + + return Container( + margin: EdgeInsets.all(1), + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(3), + ), + ); + }, + ), + ), + ); + } +}