glimmer_snake 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +2 -2
- data/TODO.md +1 -1
- data/VERSION +1 -1
- data/app/glimmer_snake/model/snake.rb +43 -17
- data/app/glimmer_snake/{model → presenter}/grid.rb +1 -1
- data/app/glimmer_snake/view/glimmer_snake.rb +8 -4
- data/glimmer_snake.gemspec +0 -0
- metadata +9 -8
- data/app/glimmer_snake/view/snake.rb +0 -91
- /data/app/glimmer_snake/{model → presenter}/cell.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0d5030c25633669f6aa7430e9afb02b1b9a9a7850b73b3739e3f9c3e55298e1
|
4
|
+
data.tar.gz: d3f3096c49d1f504fb0abdd203c0e192288d601a1e0aec8fb5922eb065c13a69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f955857df6a0162a03bb433193ca1c20d2cc055e644e4b79236421c7543105769d125c742b3143fc731d54f93c168868045a7ce9f7558a477ef98e7720c5478f
|
7
|
+
data.tar.gz: e30a1e398ca0761e87d3d4c0202cc574b08f0cda51d053b324d84b6a815e8e2b97388bdec1a36c65232fa44c3bf55fb8f26d15bab6b2bcbd62cdceb201de047a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 1.0.1
|
4
|
+
|
5
|
+
- Change snake direction on key press instead of key release to be more responsive for players who are not used to releasing pressed keys quickly
|
6
|
+
- Fix issue with detecting collision too soon if a snake fills the entire space horizontally or vertically
|
7
|
+
- Add unit tests for the Model layer
|
8
|
+
- Refactor `GlimmerSnake::Model::Snake` to be more readable like high-level game domain rules (especially `move` method)
|
9
|
+
|
3
10
|
## 1.0.0
|
4
11
|
|
5
12
|
- Initial Glimmer Snake implementation
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# <img alt="Glimmer Tetris Icon" src="https://raw.githubusercontent.com/AndyObtiva/glimmer_snake/master/icons/linux/Glimmer%20Snake.png" height=85 /> Glimmer Snake 1.0.
|
1
|
+
# <img alt="Glimmer Tetris Icon" src="https://raw.githubusercontent.com/AndyObtiva/glimmer_snake/master/icons/linux/Glimmer%20Snake.png" height=85 /> Glimmer Snake 1.0.1
|
2
2
|
## [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=40 /> Glimmer DSL for LibUI Application](https://github.com/AndyObtiva/glimmer-dsl-libui)
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer_snake.svg)](http://badge.fury.io/rb/glimmer_snake)
|
4
4
|
|
@@ -28,7 +28,7 @@ Mac | Windows | Linux
|
|
28
28
|
----|---------|------
|
29
29
|
![glimmer-dsl-libui-mac-snake.png](/screenshots/glimmer-dsl-libui-mac-snake.png) ![glimmer-dsl-libui-mac-snake-game-over.png](/screenshots/glimmer-dsl-libui-mac-snake-game-over.png) | ![glimmer-dsl-libui-windows-snake.png](/screenshots/glimmer-dsl-libui-windows-snake.png) ![glimmer-dsl-libui-windows-snake-game-over.png](/screenshots/glimmer-dsl-libui-windows-snake-game-over.png) | ![glimmer-dsl-libui-linux-snake.png](/screenshots/glimmer-dsl-libui-linux-snake.png) ![glimmer-dsl-libui-linux-snake-game-over.png](/screenshots/glimmer-dsl-libui-linux-snake-game-over.png)
|
30
30
|
|
31
|
-
The goal is for the green snake to eat the red apple and to survive for as long as possible. Every time
|
31
|
+
The goal of the game is for the green snake to eat the red apple and to survive for as long as possible. The snake always moves forward at a fixed speed. You can change the direction of the snake using arrow keys (Up is North, Right is East, Down is South, Left is West). Every time the snake eats an apple, it grows by 1 block (the size of the apple), and the apple regenerates somewhere else. If the snake hits its own body (especially after enlargement), it dies. Pressing the spacebar pauses/unpauses the game.
|
32
32
|
|
33
33
|
The game remembers the highest score by storing in `~/.glimmer-snake`. You can delete that file if you want to reset the highest score.
|
34
34
|
|
data/TODO.md
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.1
|
@@ -47,10 +47,33 @@ class GlimmerSnake
|
|
47
47
|
self.joins.clear
|
48
48
|
end
|
49
49
|
|
50
|
+
def turn_right
|
51
|
+
head.orientation = RIGHT_TURN_MAP[head.orientation]
|
52
|
+
end
|
53
|
+
|
54
|
+
def turn_left
|
55
|
+
head.orientation = LEFT_TURN_MAP[head.orientation]
|
56
|
+
end
|
57
|
+
|
50
58
|
def move
|
51
|
-
|
59
|
+
create_new_head
|
60
|
+
remove_old_tail
|
61
|
+
if detect_collision?
|
62
|
+
collide_and_die
|
63
|
+
else
|
64
|
+
append_new_head
|
65
|
+
eat_apple if detect_apple?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def remove_old_tail
|
70
|
+
@old_tail = tail.dup # save in case of growing and keeping old tail
|
71
|
+
@vertebrae.delete(tail)
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_new_head
|
52
75
|
@new_head = head.dup
|
53
|
-
case
|
76
|
+
case head.orientation
|
54
77
|
when :east
|
55
78
|
@new_head.column = (@new_head.column + 1) % @game.width
|
56
79
|
when :west
|
@@ -60,25 +83,28 @@ class GlimmerSnake
|
|
60
83
|
when :north
|
61
84
|
@new_head.row = (@new_head.row - 1) % @game.height
|
62
85
|
end
|
63
|
-
if @vertebrae.map {|v| [v.row, v.column]}.include?([@new_head.row, @new_head.column])
|
64
|
-
self.collided = true
|
65
|
-
@game.over = true
|
66
|
-
else
|
67
|
-
@vertebrae.append(@new_head)
|
68
|
-
@vertebrae.delete(tail)
|
69
|
-
if head.row == @game.apple.row && head.column == @game.apple.column
|
70
|
-
grow
|
71
|
-
@game.apple.generate
|
72
|
-
end
|
73
|
-
end
|
74
86
|
end
|
75
87
|
|
76
|
-
def
|
77
|
-
|
88
|
+
def append_new_head
|
89
|
+
@vertebrae.append(@new_head)
|
78
90
|
end
|
79
91
|
|
80
|
-
def
|
81
|
-
|
92
|
+
def detect_collision?
|
93
|
+
@vertebrae.map {|v| [v.row, v.column]}.include?([@new_head.row, @new_head.column])
|
94
|
+
end
|
95
|
+
|
96
|
+
def collide_and_die
|
97
|
+
self.collided = true
|
98
|
+
@game.over = true
|
99
|
+
end
|
100
|
+
|
101
|
+
def detect_apple?
|
102
|
+
head.row == @game.apple.row && head.column == @game.apple.column
|
103
|
+
end
|
104
|
+
|
105
|
+
def eat_apple
|
106
|
+
grow
|
107
|
+
@game.apple.generate
|
82
108
|
end
|
83
109
|
|
84
110
|
def grow
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'glimmer_snake/
|
1
|
+
require 'glimmer_snake/presenter/grid'
|
2
2
|
|
3
3
|
class GlimmerSnake
|
4
4
|
module View
|
@@ -38,13 +38,17 @@ class GlimmerSnake
|
|
38
38
|
square(0, 0, CELL_SIZE) {
|
39
39
|
fill <= [@grid.cells[row][column], :color] # data-bind square fill to grid cell color
|
40
40
|
}
|
41
|
-
|
42
|
-
|
41
|
+
|
42
|
+
on_key_down do |area_key_event|
|
43
|
+
handled = true # assume we will handle the event
|
43
44
|
if area_key_event[:key] == ' '
|
44
45
|
@game.toggle_pause
|
45
|
-
|
46
|
+
elsif %i[up right down left].include?(area_key_event[:ext_key])
|
46
47
|
@keypress_queue << area_key_event[:ext_key]
|
48
|
+
else
|
49
|
+
handled = false # we won't handle the event after all
|
47
50
|
end
|
51
|
+
handled
|
48
52
|
end
|
49
53
|
}
|
50
54
|
end
|
data/glimmer_snake.gemspec
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer_snake
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer-dsl-libui
|
@@ -66,8 +66,9 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description: Glimmer Snake game desktop application built with
|
70
|
-
|
69
|
+
description: Glimmer Snake game cross-platform desktop GUI application built with
|
70
|
+
Glimmer DSL for LibUI to run on Mac, Windows, and Linux. Gem ships with glimmer_snake
|
71
|
+
script for launching game.
|
71
72
|
email: andy.am@gmail.com
|
72
73
|
executables:
|
73
74
|
- glimmer_snake
|
@@ -85,13 +86,12 @@ files:
|
|
85
86
|
- app/glimmer_snake.rb
|
86
87
|
- app/glimmer_snake/launch.rb
|
87
88
|
- app/glimmer_snake/model/apple.rb
|
88
|
-
- app/glimmer_snake/model/cell.rb
|
89
89
|
- app/glimmer_snake/model/game.rb
|
90
|
-
- app/glimmer_snake/model/grid.rb
|
91
90
|
- app/glimmer_snake/model/snake.rb
|
92
91
|
- app/glimmer_snake/model/vertebra.rb
|
92
|
+
- app/glimmer_snake/presenter/cell.rb
|
93
|
+
- app/glimmer_snake/presenter/grid.rb
|
93
94
|
- app/glimmer_snake/view/glimmer_snake.rb
|
94
|
-
- app/glimmer_snake/view/snake.rb
|
95
95
|
- bin/glimmer_snake
|
96
96
|
- glimmer_snake.gemspec
|
97
97
|
- icons/linux/Glimmer Snake.png
|
@@ -104,7 +104,8 @@ metadata: {}
|
|
104
104
|
post_install_message:
|
105
105
|
- |2+
|
106
106
|
|
107
|
-
Glimmer Snake 1.0.
|
107
|
+
Glimmer Snake 1.0.1
|
108
|
+
was installed!
|
108
109
|
Play by running:
|
109
110
|
|
110
111
|
glimmer_snake
|
@@ -1,91 +0,0 @@
|
|
1
|
-
require 'glimmer-dsl-libui'
|
2
|
-
|
3
|
-
require_relative 'snake/presenter/grid'
|
4
|
-
|
5
|
-
class Snake
|
6
|
-
include Glimmer
|
7
|
-
|
8
|
-
CELL_SIZE = 15
|
9
|
-
SNAKE_MOVE_DELAY = 0.1
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@game = Model::Game.new
|
13
|
-
@grid = Presenter::Grid.new(@game)
|
14
|
-
@game.start
|
15
|
-
@keypress_queue = []
|
16
|
-
create_gui
|
17
|
-
register_observers
|
18
|
-
end
|
19
|
-
|
20
|
-
def launch
|
21
|
-
@main_window.show
|
22
|
-
end
|
23
|
-
|
24
|
-
def register_observers
|
25
|
-
observe(@game, :over) do |game_over|
|
26
|
-
Glimmer::LibUI.queue_main do
|
27
|
-
if game_over
|
28
|
-
msg_box('Game Over!', "Score: #{@game.score} | High Score: #{@game.high_score}")
|
29
|
-
@game.start
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
Glimmer::LibUI.timer(SNAKE_MOVE_DELAY) do
|
35
|
-
unless @game.paused? || @game.over?
|
36
|
-
process_queued_keypress
|
37
|
-
@game.snake.move
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def process_queued_keypress
|
43
|
-
# key press queue ensures one turn per snake move to avoid a double-turn resulting in instant death (due to snake illogically going back against itself)
|
44
|
-
key = @keypress_queue.shift
|
45
|
-
case [@game.snake.head.orientation, key]
|
46
|
-
in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
|
47
|
-
@game.snake.turn_right
|
48
|
-
in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
|
49
|
-
@game.snake.turn_left
|
50
|
-
else
|
51
|
-
# No Op
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def create_gui
|
56
|
-
@main_window = window {
|
57
|
-
# data-bind window title to game score, converting it to a title string on read from the model
|
58
|
-
title <= [@game, :score, on_read: -> (score) {"Snake (Score: #{@game.score})"}]
|
59
|
-
content_size @game.width * CELL_SIZE, @game.height * CELL_SIZE
|
60
|
-
resizable false
|
61
|
-
|
62
|
-
vertical_box {
|
63
|
-
padded false
|
64
|
-
|
65
|
-
@game.height.times do |row|
|
66
|
-
horizontal_box {
|
67
|
-
padded false
|
68
|
-
|
69
|
-
@game.width.times do |column|
|
70
|
-
area {
|
71
|
-
square(0, 0, CELL_SIZE) {
|
72
|
-
fill <= [@grid.cells[row][column], :color] # data-bind square fill to grid cell color
|
73
|
-
}
|
74
|
-
|
75
|
-
on_key_up do |area_key_event|
|
76
|
-
if area_key_event[:key] == ' '
|
77
|
-
@game.toggle_pause
|
78
|
-
else
|
79
|
-
@keypress_queue << area_key_event[:ext_key]
|
80
|
-
end
|
81
|
-
end
|
82
|
-
}
|
83
|
-
end
|
84
|
-
}
|
85
|
-
end
|
86
|
-
}
|
87
|
-
}
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
Snake.new.launch
|
File without changes
|