Skip to content

Commit

Permalink
Merge pull request #25 from ivan1993spb/dev
Browse files Browse the repository at this point in the history
Release 2/20/2020 - v1.1.0

What's new:

- SEO friendly tags
  * title
  * meta description
  * meta keyworkds
- Unknown objects can be displayed
- Ability to be changed for walls
- Flag to enable or disable walls for a new game
- WhatsApp share button
- Delete share buttons for VK and OK

Also:

- Minor design futures and fixes
- Small refactoring
  • Loading branch information
ivan1993spb authored Feb 20, 2020
2 parents eb96536 + b4fe8fa commit a5cb6a9
Show file tree
Hide file tree
Showing 20 changed files with 2,840 additions and 66 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2019 Ivan Pushkin
Copyright (c) 2020 Ivan Pushkin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "snake-lightweight-client",
"version": "0.1.0",
"version": "1.1.0",
"license": "MIT",
"private": true,
"author": {
Expand Down
4 changes: 4 additions & 0 deletions public/font-awesome-4.7.0/css/font-awesome.min.css

Large diffs are not rendered by default.

Binary file added public/font-awesome-4.7.0/fonts/FontAwesome.otf
Binary file not shown.
Binary file not shown.
2,671 changes: 2,671 additions & 0 deletions public/font-awesome-4.7.0/fonts/fontawesome-webfont.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
6 changes: 4 additions & 2 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="Snake Online - is a multiplayer version of the famous classic snake arcade game. Eat apples, watermelons and small snakes and try not to be caught or eaten by your enemies!">
<meta name="keywords" content="snake,online,arcade,multiplayer,game">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<title>Snake Online</title>
<link rel="stylesheet" href="<%= BASE_URL %>font-awesome-4.7.0/css/font-awesome.min.css">
<title>Snake Online - Multiplayer Snake Arcade Game</title>
</head>
<body>
<noscript>
Expand Down
2 changes: 1 addition & 1 deletion src/assets/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
body {
margin: 0;
padding: 0;
background: #000;
background: #111;
}

a {
Expand Down
28 changes: 28 additions & 0 deletions src/common/helpers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,32 @@

const DEFAULT_CLIENT_WIDTH = 1200
const DEFAULT_CLIENT_HEIGHT = 800

export const clientSizePx = () => {
return {
width: window.innerWidth || document.documentElement.clientWidth ||
document.body.clientWidth || DEFAULT_CLIENT_WIDTH,
height: window.innerHeight || document.documentElement.clientHeight ||
document.body.clientHeight || DEFAULT_CLIENT_HEIGHT
}
}

export const clientScrollPx = () => {
return {
scrollTop: window.pageYOffset || document.documentElement.scrollTop ||
document.body.scrollTop,
scrollLeft: window.pageXOffset || document.documentElement.scrollLeft ||
document.body.scrollLeft
}
}

export const clientPx = () => {
return {
clientTop: document.documentElement.clientTop || document.body.clientTop || 0,
clientLeft: document.documentElement.clientLeft || document.body.clientLeft || 0
}
}

export const detectMobileAndroidDevice = () => navigator.userAgent.match(/Android/i)

export const detectMobileWebOSDevice = () => navigator.userAgent.match(/webOS/i)
Expand Down
1 change: 1 addition & 0 deletions src/components/Playground.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export default {
background: #040;
opacity: 0.6;
cursor: default;
user-select: none;
text-align: center;
vertical-align: middle;
Expand Down
9 changes: 2 additions & 7 deletions src/components/SocialSharingBlock.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,8 @@
</network>
</div>
<div>
<network network="vk" id="vk">
<i class="fa fa-fw fa-vk"></i> VK
</network>
</div>
<div>
<network network="odnoklassniki" id="odnoklassniki">
<i class="fa fa-fw fa-odnoklassniki"></i> Ok
<network network="whatsapp">
<i class="fa fa-whatsapp"></i> Whatsapp
</network>
</div>
<div>
Expand Down
5 changes: 5 additions & 0 deletions src/game/Canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const OBJECT_WATERMELON = 4
export const OBJECT_WALL = 5
export const OBJECT_HIGHLIGHTED = 6
export const OBJECT_MOUSE = 7
export const OBJECT_UNKNOWN = 8

export const COLOR_BORDER = '#010'
export const COLOR_GRID = '#020'
Expand All @@ -18,6 +19,7 @@ export const COLOR_WATERMELON = '#ff0'
export const COLOR_WALL = '#474'
export const COLOR_HIGHLIGHTED = '#f88'
export const COLOR_MOUSE = '#f00'
export const COLOR_UNKNOWN = '#666'

const ERROR_INVALID_DOT_SIZE = 'invalid dot size'
const ERROR_INVALID_LINE_SIZE = 'invalid line size'
Expand Down Expand Up @@ -146,6 +148,9 @@ export class Canvas {
case OBJECT_MOUSE:
this._draw(this._contextGame, COLOR_MOUSE, dots)
break
case OBJECT_UNKNOWN:
this._draw(this._contextGame, COLOR_UNKNOWN, dots)
break
default:
throw new Error(`Canvas.draw: invalid type ${type}`)
}
Expand Down
68 changes: 62 additions & 6 deletions src/game/Playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
OBJECT_WALL,
OBJECT_WATERMELON,
OBJECT_HIGHLIGHTED,
OBJECT_MOUSE
OBJECT_MOUSE,
OBJECT_UNKNOWN
} from './Canvas'

const OBJECT_TYPE_SNAKE = 'snake'
Expand Down Expand Up @@ -175,6 +176,13 @@ export class Playground {
this._canvas.draw(OBJECT_WATERMELON, food.dots)
} else if (food.type === OBJECT_TYPE_MOUSE) {
this._canvas.draw(OBJECT_MOUSE, [food.dot])
} else {
// Unknown object
if (_.has(food, 'dots')) {
this._canvas.draw(OBJECT_UNKNOWN, food.dots)
} else if (_.has(food, 'dot')) {
this._canvas.draw(OBJECT_UNKNOWN, [food.dot])
}
}
})

Expand Down Expand Up @@ -249,7 +257,15 @@ export class Playground {
this._cacheFood.set(object.id, object)
break
default:
throw new Error(`Playground: error cannot create object of invalid type: ${object.type}`)
// Add all unknown objects to the cache map for food
if (_.has(object, 'dots')) {
this._canvas.draw(OBJECT_UNKNOWN, object.dots)
} else if (_.has(object, 'dot')) {
this._canvas.draw(OBJECT_UNKNOWN, [object.dot])
} else {
throw new Error(`Playground: object of unknown type does not have dot/dots field: ${object.type}`)
}
this._cacheFood.set(object.id, object)
}
}

Expand Down Expand Up @@ -314,11 +330,37 @@ export class Playground {
break
}
case OBJECT_TYPE_WALL: {
// Nothing to do here.
throw new Error('Playground: cannot update wall object')
const wall = this._cacheWalls.get(object.id)
if (wall === undefined) {
throw new Error(`Playground: wall to update was not found: ${object.id}`)
}
const { clear, draw } = dotListsDifference(object.dots, wall.dots)
this._canvas.draw(OBJECT_WALL, draw)
this._canvas.clear(OBJECT_WALL, clear)
this._cacheWalls.set(object.id, object)
break
}
default: {
throw new Error(`Playground: error cannot update object of invalid type: ${object.type}`)
// All unknown objects are stored in the cache map for food
const unknown = this._cacheFood.get(object.id)
if (unknown === undefined) {
throw new Error(`Playground: unknown object to be updated was not found: ${object.id}`)
}

if (_.has(object, 'dots')) {
const { clear, draw } = dotListsDifference(object.dots, unknown.dots)
this._canvas.draw(OBJECT_UNKNOWN, draw)
this._canvas.clear(OBJECT_UNKNOWN, clear)
} else if (_.has(object, 'dot')) {
if (!dotsEqual(object.dot, unknown.dot)) {
this._canvas.draw(OBJECT_UNKNOWN, [object.dot])
this._canvas.clear(OBJECT_UNKNOWN, [unknown.dot])
}
} else {
throw new Error(`Playground: object of unknown type does not have dot/dots field: ${object.type}`)
}

this._cacheFood.set(object.id, object)
}
}
}
Expand Down Expand Up @@ -375,7 +417,21 @@ export class Playground {
break
}
default:
throw new Error(`Playground: error cannot delete object of invalid type: ${object.type}`)
// All unknown objects are stored in the cache map for food
const unknown = this._cacheFood.get(object.id)
if (unknown === undefined) {
throw new Error(`Playground: unknown object to be deleted was not found: ${object.id}`)
}

if (_.has(object, 'dots')) {
this._canvas.clear(OBJECT_UNKNOWN, unknown.dots)
} else if (_.has(object, 'dot')) {
this._canvas.clear(OBJECT_UNKNOWN, [unknown.dot])
} else {
throw new Error(`Playground: object of unknown type does not have dot/dots field: ${object.type}`)
}

this._cacheFood.delete(object.id)
}
}

Expand Down
33 changes: 5 additions & 28 deletions src/game/ScreenSizeController.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@

import _ from 'lodash'
import {
clientSizePx,
clientScrollPx,
clientPx
} from '@/common/helpers'

const LISTEN_TO_EVENT = 'resize'
const THROTTLE_WAIT = 1000

const DEFAULT_CLIENT_WIDTH = 1200
const DEFAULT_CLIENT_HEIGHT = 800

const LINE_SIZE_MIN = 1
const LINE_SIZE_PERCENT = 0.10
const DOT_SIZE_MIN = 5
Expand All @@ -16,31 +18,6 @@ const BORDER_SIZE = 2
const SCREEN_WIDTH_LIMIT = 600
const SCREEN_HEIGHT_LIMIT = 600

function clientSizePx () {
return {
width: window.innerWidth || document.documentElement.clientWidth ||
document.body.clientWidth || DEFAULT_CLIENT_WIDTH,
height: window.innerHeight || document.documentElement.clientHeight ||
document.body.clientHeight || DEFAULT_CLIENT_HEIGHT
}
}

function clientScrollPx () {
return {
scrollTop: window.pageYOffset || document.documentElement.scrollTop ||
document.body.scrollTop,
scrollLeft: window.pageXOffset || document.documentElement.scrollLeft ||
document.body.scrollLeft
}
}

function clientPx () {
return {
clientTop: document.documentElement.clientTop || document.body.clientTop || 0,
clientLeft: document.documentElement.clientLeft || document.body.clientLeft || 0
}
}

export class ScreenSizeController {
constructor (mapWidthDots, mapHeightDots, divCanvasHeight) {
this._mapWidthDots = mapWidthDots
Expand Down
17 changes: 16 additions & 1 deletion src/views/Games.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<div class="games-page-block">Games count: {{ count }}/{{ limit }}</div>

<div class="games-page-block" v-if="count < limit">
<router-link to="/new">create game</router-link>
<router-link class="games-page-block-new-game-button" to="/new">New game</router-link>
</div>

<div class="games-page-block" v-if="count > 0">
Expand Down Expand Up @@ -81,6 +81,21 @@ export default {
.games-page-block {
margin: 20px 0px;
&-new-game-button {
cursor: pointer;
display: inline-block;
font-weight: bold;
text-decoration: none;
padding: 7px 20px;
background: #494;
color: #fff;
}
&-new-game-button:hover {
background: #fff;
color: #494;
}
}
h1 {
Expand Down
30 changes: 25 additions & 5 deletions src/views/New.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="new">
<h1>Create new game</h1>
<h1>New game</h1>
<div class="new-content">
<h3>Map size</h3>
<div class="new-content-row">
Expand All @@ -19,6 +19,11 @@
<input id="limit-range" type="range" min="1" max="100" step="1" v-model="limit">
<input id="limit-number" type="number" v-model="limit"/>
</div>
<h3>Gameplay preferences</h3>
<div class="new-content-row">
<label for="enable-walls">Enable walls</label>
<input id="enable-walls" type="checkbox" v-model="enableWalls">
</div>
<div class="new-content-row">
<div class="new-content-row-button" @click="create">OK</div>
</div>
Expand All @@ -29,6 +34,11 @@
<script>
import store from '@/store'
import { CREATE_GAME } from '@/store/actions.type'
import { clientSizePx } from '@/common/helpers'
const INITIAL_MAP_WIDTH = 30
const INITIAL_MINIMUM_LIMIT = 5
const INITIAL_LIMIT_MAP_FACTOR = 0.01
export default {
name: 'new',
Expand All @@ -39,15 +49,25 @@ export default {
store.dispatch(CREATE_GAME, {
width: this.width,
height: this.height,
limit: this.limit
limit: this.limit,
'enable_walls': this.enableWalls
})
}
},
data () {
const {
width: widthPx,
height: heightPx
} = clientSizePx()
const width = INITIAL_MAP_WIDTH
const height = Math.ceil(width * heightPx / widthPx)
const limit = Math.max(INITIAL_MINIMUM_LIMIT, Math.ceil(width * height * INITIAL_LIMIT_MAP_FACTOR))
return {
width: 30,
height: 30,
limit: 5
width,
height,
limit,
enableWalls: true
}
}
}
Expand Down
Loading

0 comments on commit a5cb6a9

Please sign in to comment.