A new Smaug project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

165 lines
5.2 KiB

# coding: utf-8
################################
# So I was working on a snake game while
# learning DragonRuby, and at some point I had a thought
# what if I use "๐Ÿ˜€" as a function name, surely it wont work right...?
# RIGHT....?
# BUT IT DID, IT WORKED
# it all went downhill from then
# Created by Anton K. (ai Doge)
# https://gist.github.com/scorp200
#############LICENSE############
# Feel free to use this anywhere and however you want
# You can sell this to EA for $1,000,000 if you want, its completely free.
# Just rememeber you are helping this... thing... to spread...
# ALSO! I am not liable for any mental, physical or financial damage caused.
#############LICENSE############
class Array
#Helper function
def move! vector
self.x += vector.x
self.y += vector.y
return self
end
#Helper function to draw snake body
def draw! ๐ŸŽฎ, ๐Ÿ“บ, color
translate ๐Ÿ“บ.solids, ๐ŸŽฎ.โ›“, [self.x * ๐ŸŽฎ.โš–๏ธ + ๐ŸŽฎ.๐Ÿ›ถ / 2, self.y * ๐ŸŽฎ.โš–๏ธ + ๐ŸŽฎ.๐Ÿ›ถ / 2, ๐ŸŽฎ.โš–๏ธ - ๐ŸŽฎ.๐Ÿ›ถ, ๐ŸŽฎ.โš–๏ธ - ๐ŸŽฎ.๐Ÿ›ถ, color]
end
#This is where it all started, I was trying to find good way to multiply a map by a number, * is already used so is **
#I kept trying different combinations of symbols, when suddenly...
def ๐Ÿ˜€ value
self.map {|d| d * value}
end
end
#Draw stuff with an offset
def translate output_collection, โ›“, what
what.x += โ›“.x
what.y += โ›“.y
output_collection << what
end
BLUE = [33, 150, 243]
RED = [244, 67, 54]
GOLD = [255, 193, 7]
LAST = 0
def tick args
defaults args.state
render args.state, args.outputs
input args.state, args.inputs
update args.state
end
def update ๐ŸŽฎ
#Update every 10 frames
if ๐ŸŽฎ.tick_count.mod_zero? 10
#Add new snake body piece at head's location
๐ŸŽฎ.๐Ÿ << [*๐ŸŽฎ.๐Ÿค–]
#Assign Next Direction to Direction
๐ŸŽฎ.๐Ÿš— = *๐ŸŽฎ.๐Ÿšฆ
#Trim the snake a bit if its longer than current size
if ๐ŸŽฎ.๐Ÿ.length > ๐ŸŽฎ.๐Ÿ›’
๐ŸŽฎ.๐Ÿ = ๐ŸŽฎ.๐Ÿ[-๐ŸŽฎ.๐Ÿ›’..-1]
end
#Move the head in the Direction
๐ŸŽฎ.๐Ÿค–.move! ๐ŸŽฎ.๐Ÿš—
#If Head is outside the playing field, or inside snake's body restart game
if ๐ŸŽฎ.๐Ÿค–.x < 0 || ๐ŸŽฎ.๐Ÿค–.x >= ๐ŸŽฎ.๐Ÿ—บ.x || ๐ŸŽฎ.๐Ÿค–.y < 0 || ๐ŸŽฎ.๐Ÿค–.y >= ๐ŸŽฎ.๐Ÿ—บ.y || ๐ŸŽฎ.๐Ÿš— != [0, 0] && ๐ŸŽฎ.๐Ÿ.any? {|s| s == ๐ŸŽฎ.๐Ÿค–}
LAST = ๐ŸŽฎ.๐Ÿ’ฐ
๐ŸŽฎ.as_hash.clear
return
end
#If head lands on food add size and score
if ๐ŸŽฎ.๐Ÿค– == ๐ŸŽฎ.๐ŸŽ
๐ŸŽฎ.๐Ÿ›’ += 1
๐ŸŽฎ.๐Ÿ’ฐ += (๐ŸŽฎ.๐Ÿ›’ * 0.8).floor.to_i + 5
spawn_๐ŸŽ ๐ŸŽฎ
puts ๐ŸŽฎ.๐ŸŽ
end
end
#Every second remove 1 point
if ๐ŸŽฎ.๐Ÿ’ฐ > 0 && ๐ŸŽฎ.tick_count.mod_zero?(60)
๐ŸŽฎ.๐Ÿ’ฐ -= 1
end
end
def spawn_๐ŸŽ ๐ŸŽฎ
#Food
๐ŸŽฎ.๐ŸŽ ||= [*๐ŸŽฎ.๐Ÿค–]
#Randomly spawns food inside the playing field, keep doing this if the food keeps landing on the snake's body
while ๐ŸŽฎ.๐Ÿ.any? {|s| s == ๐ŸŽฎ.๐ŸŽ} || ๐ŸŽฎ.๐ŸŽ == ๐ŸŽฎ.๐Ÿค– do
๐ŸŽฎ.๐ŸŽ = [rand(๐ŸŽฎ.๐Ÿ—บ.x), rand(๐ŸŽฎ.๐Ÿ—บ.y)]
end
end
def render ๐ŸŽฎ, ๐Ÿ“บ
#Paint the background black
๐Ÿ“บ.solids << [0, 0, 1280, 720, 0, 0, 0, 255]
#Draw a border for the playing field
translate ๐Ÿ“บ.borders, ๐ŸŽฎ.โ›“, [0, 0, ๐ŸŽฎ.๐Ÿ—บ.x * ๐ŸŽฎ.โš–๏ธ, ๐ŸŽฎ.๐Ÿ—บ.y * ๐ŸŽฎ.โš–๏ธ, 255, 255, 255]
#Draw the snake's body
๐ŸŽฎ.๐Ÿ.map do |๐Ÿ| ๐Ÿ.draw! ๐ŸŽฎ, ๐Ÿ“บ, BLUE end
#Draw the head
๐ŸŽฎ.๐Ÿค–.draw! ๐ŸŽฎ, ๐Ÿ“บ, BLUE
#Draw the food
๐ŸŽฎ.๐ŸŽ.draw! ๐ŸŽฎ, ๐Ÿ“บ, RED
#Draw current score
translate ๐Ÿ“บ.labels, ๐ŸŽฎ.โ›“, [5, 715, "Score: #{๐ŸŽฎ.๐Ÿ’ฐ}", GOLD]
#Draw your last score, if any
translate ๐Ÿ“บ.labels, ๐ŸŽฎ.โ›“, [[*๐ŸŽฎ.๐Ÿค–.๐Ÿ˜€(๐ŸŽฎ.โš–๏ธ)].move!([0, ๐ŸŽฎ.โš–๏ธ * 2]), "Your Last score is #{LAST}", 0, 1, GOLD] unless LAST == 0 || ๐ŸŽฎ.๐Ÿš— != [0, 0]
#Draw starting message, only if Direction is 0
translate ๐Ÿ“บ.labels, ๐ŸŽฎ.โ›“, [๐ŸŽฎ.๐Ÿค–.๐Ÿ˜€(๐ŸŽฎ.โš–๏ธ), "Press any Arrow key to start", 0, 1, GOLD] unless ๐ŸŽฎ.๐Ÿš— != [0, 0]
end
def input ๐ŸŽฎ, ๐Ÿ•น
#Left and Right keyboard input, only change if X direction is 0
if ๐Ÿ•น.keyboard.key_held.left && ๐ŸŽฎ.๐Ÿš—.x == 0
๐ŸŽฎ.๐Ÿšฆ = [-1, 0]
elsif ๐Ÿ•น.keyboard.key_held.right && ๐ŸŽฎ.๐Ÿš—.x == 0
๐ŸŽฎ.๐Ÿšฆ = [1, 0]
end
#Up and Down keyboard input, only change if Y direction is 0
if ๐Ÿ•น.keyboard.key_held.up && ๐ŸŽฎ.๐Ÿš—.y == 0
๐ŸŽฎ.๐Ÿšฆ = [0, 1]
elsif ๐Ÿ•น.keyboard.key_held.down && ๐ŸŽฎ.๐Ÿš—.y == 0
๐ŸŽฎ.๐Ÿšฆ = [0, -1]
end
end
def defaults ๐ŸŽฎ
#Playing field size
๐ŸŽฎ.๐Ÿ—บ ||= [20, 20]
#Scale for drawing, screen height / Field height
๐ŸŽฎ.โš–๏ธ ||= 720 / ๐ŸŽฎ.๐Ÿ—บ.y
#Offset, offset all rendering to the center of the screen
๐ŸŽฎ.โ›“ ||= [(1280 - 720).fdiv(2), 0]
#Padding, make the snake body slightly smaller than the scale
๐ŸŽฎ.๐Ÿ›ถ ||= (๐ŸŽฎ.โš–๏ธ * 0.2).to_i
#Snake Size
๐ŸŽฎ.๐Ÿ›’ ||= 3
#Snake head, the only part we are actually controlling
๐ŸŽฎ.๐Ÿค– ||= [๐ŸŽฎ.๐Ÿ—บ.x / 2, ๐ŸŽฎ.๐Ÿ—บ.y / 2]
#Snake body map, follows the head
๐ŸŽฎ.๐Ÿ ||= []
#Direction the head moves to
๐ŸŽฎ.๐Ÿš— ||= [0, 0]
#Next_Direction, during input check only change this variable and then when game updates asign this to Direction
๐ŸŽฎ.๐Ÿšฆ ||= [*๐ŸŽฎ.๐Ÿš—]
#Your score
๐ŸŽฎ.๐Ÿ’ฐ ||= 0
#Spawns Food randomly
spawn_๐ŸŽ(๐ŸŽฎ) unless ๐ŸŽฎ.๐ŸŽ?
end