Skip to content

Instantly share code, notes, and snippets.

@AndreiRudenko
Created April 23, 2018 02:45
Show Gist options
  • Save AndreiRudenko/a3f62fd84140cb83780a05572fb8bf7e to your computer and use it in GitHub Desktop.
Save AndreiRudenko/a3f62fd84140cb83780a05572fb8bf7e to your computer and use it in GitHub Desktop.
Ludum Dare 41 source code for TIC-80 game, written in wren language
// author: Andrei Rudenko
// desc: ld41
// script: wren
import "random" for Random
class Maths {
static clamp(value, a, b) { ( value < a ) ? a : ( ( value > b ) ? b : value ) }
static sign( x ) { (x >= 0) ? 1 : -1 }
static ispow2(n) { (n & (n - 1)) == 0 }
static mod(a,b) {
var r = a % b
return r < 0 ? r + b : r
}
}
class Utils {
static list_remove(l,v){
for (i in 0...l.count) {
if (l[i] == v) {
l.removeAt(i)
return true
}
}
return false
}
static list_has(l,v){
for (o in l) {
if (o == v) return true
}
return false
}
}
class Timer {
static time(){ 0}
static init(){
__timers = []
}
static add(t){
__timers.add(t)
return t
}
static remove(t){
var ot = null
for (i in 0...__timers.count) {
if (ot == __timers[i]) {
__timers.removeAt(i)
break
}
}
}
static schedule(tl){ schedule_from(0, tl, null) }
static schedule(tl, cb){ schedule_from(0, tl, cb) }
static schedule_from(ct, tl){ schedule_from(ct, tl, null) }
static schedule_from(ct, tl, cb){
var t = Timer.new()
t.start_from(ct, tl, cb)
return t
}
static update(dt){
for (t in __timers) {
if (t.active && !t.finished && t.time_limit >= 0){
t.update(dt)
}
}
}
time_limit { _time_limit }
time_limit=(v) { _time_limit = v }
loops { _loops }
loops=(v) { _loops = v }
active { _active }
active=(v) { _active = v }
elapsed_time { _time }
elapsed_time=(v) { _time = v }
use_timescale { _use_ts }
use_timescale=(v) { _use_ts = v }
finished { _finished }
elapsed_loops { _loops_counter }
time_left { _time_limit - _time }
loops_left { _loops - _loops_counter }
progress { (_time_limit > 0) ? (_time / _time_limit) : 0 }
construct new(){
_time = 0
_time_limit = 0
_start_time = 0
_loops = 0
_loops_counter = 0
_inarray = false
_active = true
_use_ts = true
_finished = false
}
start(tl) { start_from(0, tl, null) }
start(tl, cb) { start_from(0, tl, cb) }
start_from(st, tl) { start_from(st, tl, null) }
start_from(st, tl, cb) {
stop(false)
if (!_inarray) {
Timer.add(this)
_inarray = true
}
_active = true
_finished = false
if(cb != null){
_oncomplete = cb
}
_time_limit = tl.abs
_start_time = (_time_limit..st).min
_time = _start_time
_loops = 1
_loops_counter = 0
return this
}
reset() { reset(-1) }
reset(newtime) {
if (newtime >= 0) {
time_limit = newtime
}
finished = false
_time = 0 // _start_time ?
// loops = 1
_loops_counter = 0
return this
}
repeat() { repeat(0) }
repeat(t) {
loops = t.abs
return this
}
stop() { stop(true) }
stop(finish) {
if(!_finished) {
_finished = true
_active = false
if (_inarray){
Timer.remove(this)
_inarray = false
}
if (finish && _oncomplete != null) {
_oncomplete.call()
}
}
}
oncomplete(cb){
_oncomplete = cb
return this
}
onrepeat(cb){
_onrepeat = cb
return this
}
onupdate(cb){
_onupdate = cb
return this
}
update(dt){
if (_use_ts) dt = dt * Game.timescale
_time = _time + dt
if (_onupdate != null) _onupdate.call()
while (!_finished && _time_limit < _time) {
_loops_counter = _loops_counter + 1
if (_loops > 0 && (_loops_counter >= _loops)) {
stop()
break
}
_time = _time - _time_limit
if (_onrepeat != null) _onrepeat.call()
}
}
}
class Text {
x { _x }
y { _y }
scale { _sc }
color { _clr }
text { _txt }
x=(v) { _x=v }
y=(v) { _y=v }
scale=(v) { _sc=v }
color=(v) { _clr=v }
text=(v) { _txt=v }
construct new(txt,x,y,clr,sc) {
_txt = txt
_x = x
_y = y
_sc = sc
_clr = clr
}
draw() {
TIC.print(_txt,_x,_y,_clr,false,_sc)
}
}
class Words {
static init(){
__used = []
__words = []
// 2 letter words
__words.add([
"AA", "AB", "AD", "AE", "AG", "AH", "AI", "AL", "AM", "AN", "AR", "AS", "AT", "AW", "AX", "AY", "BA", "BE", "BI", "BO", "BY", "DE", "DO", "ED",
"EF", "EH", "EL", "EM", "EN", "ER", "ES", "ET", "EX", "FA", "FE", "GO", "HA", "HE", "HI", "HM", "HO", "ID", "IF", "IN", "IS", "IT", "JO", "KA",
"KI", "LA", "LI", "LO", "MA", "ME", "MI", "MM", "MO", "MU", "MY", "NA", "NE", "NO", "NU", "OD", "OE", "OF", "OH", "OI", "OM", "ON", "OP", "OR",
"OS", "OW", "OX", "OY", "PA", "PE", "PI", "QI", "RE", "SH", "SI", "SO", "TA", "TI", "TO", "UH", "UM", "UN", "UP", "US", "UT", "WE", "WO", "XI",
"XU", "YA", "YE", "YO", "ZA"
])
// 3 letter words
__words.add([
"AID","AIM","AIR","AWE","FIT",
"FTW","FUN","GOD","HOT","JOY",
"NEW","OMG","PEP","VIM","VOW",
"WIN","WON","WOW","YAY","YEA",
"YEN","YES"
])
// 4 letter words
__words.add([
"ABLE", "AMIN", "AWED", "BEST", "BRIO",
"CALM", "CARE", "COOL", "CUTE", "DOPE",
"DUTY", "EASE", "EASY", "FAIR", "FAME",
"FINE", "FLOW", "FOOD", "FREE", "GIFT",
"GIVE", "GLAD", "GLOW", "GOOD", "GROW",
"HALO", "HELP", "HERO", "HOLY", "HOPE",
"HUGE", "IDEA", "JOKE", "JUST", "KEEN",
"KIND", "KISS", "LIFE", "LIKE", "LIVE",
"LOVE", "LUCK", "MANY", "MILD", "MORE",
"NEAT", "NICE", "OPEN", "PLAY", "PURE",
"REAL", "REST", "RIPE", "SAFE", "SAVE",
"SEXY", "SOUL", "SWAG", "TACT", "TEAM",
"TIME", "TRUE", "VERY", "WARM", "WELL",
"WILL", "WISE", "YEAH", "ZANY", "ZEAL",
"ZEST", "ZING"
])
// 5 letter words
__words.add([
"ADORE", "AGILE", "AGREE", "ALERT", "ALIVE",
"ALLOW", "ALOHA", "AMAZE", "AMITY", "AMPLE",
"AMPLY", "AMUSE", "ANGEL", "ARDOR", "AWARE",
"BLESS", "BLISS", "BLOOM", "BONUS", "CHAMP",
"CHARM", "CLEAN", "CLEAR", "DANDY", "DREAM",
"DRIVE", "EAGER", "ENJOY", "EXTRA", "FAITH",
"FANCY", "FOCUS", "GIDDY", "GIGIL", "GLORY",
"GRACE", "GRAND", "GREAT", "GUIDE", "HAPPY",
"HEART", "HELLO", "HONOR", "HUMAN", "HUMOR",
"INNER", "JOLLY", "KALON", "KILIG", "LAUGH",
"LEARN", "LIGHT", "LOGIC", "LOYAL", "LUCKY",
"MAGIC", "MAJOR", "MENCH", "MERCY", "MERIT",
"MOVED", "NOBLE", "ORDER", "PEACE", "PIOUS",
"POWER", "PRIDE", "PROTO", "PROUD", "QUIET",
"READY", "RELAX", "RENEW", "SCOPE", "SERVE",
"SHINE", "SKILL", "SLEEP", "SMART", "SMILE",
"SPACE", "SPARK", "START", "STILL", "STUDY",
"STYLE", "SWEET", "TEACH", "TEMUL", "THANK",
"TOUCH", "TRUST", "TRUTH", "UNITY", "VALID",
"VALUE", "VIGOR", "WATER", "WHOLE", "WORTH",
"YEARN", "YOUNG", "YOUTH", "YUGEN", "YUMMY",
"ZAPPY", "ZESTY", "ZIPPY"
])
}
static is_used(i) {
return Utils.list_has(__used, i)
}
static clear_used(){
__used = []
}
static get_word(l) {
return __words[l-2]
}
static get_random(l) {
var words = __words[l-2]
var r = Game.random.int(0,words.count)
if (is_used(r)) {
return Words.get_random(l)
} else {
__used.add(r)
return words[r]
}
}
static to_array(word){
var arr = []
for (l in word) {
arr.add(Letters.to_id(l))
}
return arr
}
}
class Letters {
static init() {
__used = []
}
static is_used(i) {
return Utils.list_has(__used, i)
}
static clear_used(){
__used = []
}
static get_random() {
if (__used.count == 26) Fiber.abort("we dont have any letters anymore")
var r = Game.random.int(1,27)
if (is_used(r)) {
return Letters.get_random()
} else {
__used.add(r)
return r
}
}
static to_id(i){
if(i == "A") {
return 1
} else if(i == "B") {
return 2
} else if(i == "C") {
return 3
} else if(i == "D") {
return 4
} else if(i == "E") {
return 5
} else if(i == "F") {
return 6
} else if(i == "G") {
return 7
} else if(i == "H") {
return 8
} else if(i == "I") {
return 9
} else if(i == "J") {
return 10
} else if(i == "K") {
return 11
} else if(i == "L") {
return 12
} else if(i == "M") {
return 13
} else if(i == "N") {
return 14
} else if(i == "O") {
return 15
} else if(i == "P") {
return 16
} else if(i == "Q") {
return 17
} else if(i == "R") {
return 18
} else if(i == "S") {
return 19
} else if(i == "T") {
return 20
} else if(i == "U") {
return 21
} else if(i == "V") {
return 22
} else if(i == "W") {
return 23
} else if(i == "X") {
return 24
} else if(i == "Y") {
return 25
} else if(i == "Z") {
return 26
}
}
static from_id(i) {
if(i == 1) {
return "A"
} else if(i == 2) {
return "B"
} else if(i == 3) {
return "C"
} else if(i == 4) {
return "D"
} else if(i == 5) {
return "E"
} else if(i == 6) {
return "F"
} else if(i == 7) {
return "G"
} else if(i == 8) {
return "H"
} else if(i == 9) {
return "I"
} else if(i == 10) {
return "J"
} else if(i == 11) {
return "K"
} else if(i == 12) {
return "L"
} else if(i == 13) {
return "M"
} else if(i == 14) {
return "N"
} else if(i == 15) {
return "O"
} else if(i == 16) {
return "P"
} else if(i == 17) {
return "Q"
} else if(i == 18) {
return "R"
} else if(i == 19) {
return "S"
} else if(i == 20) {
return "T"
} else if(i == 21) {
return "U"
} else if(i == 22) {
return "V"
} else if(i == 23) {
return "W"
} else if(i == 24) {
return "X"
} else if(i == 25) {
return "Y"
} else if(i == 26) {
return "Z"
}
}
}
class Key {
static callback { __cb }
static callback=(v) { __cb=v }
static init() {
__cb = null
__last_pressed = []
}
static clear_pressed() {
__last_pressed = []
}
static update() {
for (i in 1...27) {
if (TIC.key(i) && Utils.list_has(__last_pressed,i)) {
return
} else if (TIC.key(i)) {
if (__cb != null) {
__cb.call(i)
__last_pressed.add(i)
}
return
}
}
clear_pressed()
}
}
class Point {
x { _x }
y { _y }
x=(v) { _x=v }
y=(v) { _y=v }
construct new(x,y) {
_x = x
_y = y
}
}
class Food is Point {
construct new(x,y) { super(x,y) }
draw() {
TIC.rect(x*8, y*8, 8, 8, 2)
}
}
class Direction {
static up { __up }
static down { __down }
static left { __left }
static right { __right }
static up_id { 1 }
static right_id { 2 }
static down_id { 4 }
static left_id { 8 }
static init() {
__up = Direction.new(1,Point.new(0,-1))
__down = Direction.new(2,Point.new(0,1))
__left = Direction.new(4,Point.new(-1,0))
__right = Direction.new(8,Point.new(1,0))
}
static get(d) {
if (d == 1) {
return __up
}else if (d == 2) {
return __right
}else if (d == 4) {
return __down
}else if (d == 8) {
return __left
}
}
id { _id }
vec { _vec }
letters { _letters }
construct new(id,vec) {
_id = id
_vec = vec
_letters = []
_matched = []
}
set_letters(l) {
_letters = l
}
match_letter(id) {
if (_letters.count > 0) {
return _letters[0] == id
}
return false
}
remove_letter(id) {
return Utils.list_remove(_letters, id)
}
pressed() {
for (k in _letters) {
if (TIC.key(k)){
return true
}
}
return false
}
}
class BodyPart is Point {
tid { _tid }
tid=(v) { _tid=v }
construct new(tid,x,y) {
super(x,y)
_tid = tid
}
draw() {
}
}
class Snake {
head { _body[_body.count-1] }
neck { _body[_body.count-2] }
tail { _body[0] }
body { _body }
construct new(d,x,y) {
_body = []
if (d == 0) {
_body.add(BodyPart.new(0,x,y+2))
_body.add(BodyPart.new(0,x,y+1))
_body.add(BodyPart.new(0,x,y))
_next_dir = Direction.up
} else if (d == 1) {
_body.add(BodyPart.new(0,x-2,y))
_body.add(BodyPart.new(0,x-1,y))
_body.add(BodyPart.new(0,x,y))
_next_dir = Direction.right
} else if (d == 2) {
_body.add(BodyPart.new(0,x,y-2))
_body.add(BodyPart.new(0,x,y-1))
_body.add(BodyPart.new(0,x,y))
_next_dir = Direction.down
} else if (d == 3) {
_body.add(BodyPart.new(0,x+2,y))
_body.add(BodyPart.new(0,x+1,y))
_body.add(BodyPart.new(0,x,y))
_next_dir = Direction.left
}
switch_dir()
_can_switch = true
Timer.schedule(1,Fn.new {
Key.callback = Fn.new {|i|
onkeypressed(i)
}
})
}
switch_dir() {
if (_next_dir == Direction.left || _next_dir == Direction.right) {
var arr1 = []
var arr2 = []
if (Game.diff > 1) {
var w1 = Words.get_random(Game.diff)
var w2 = Words.get_random(Game.diff)
arr1 = Words.to_array(w1)
arr2 = Words.to_array(w2)
} else {
arr1.add(Letters.get_random())
arr2.add(Letters.get_random())
}
Direction.up.set_letters(arr1)
Direction.down.set_letters(arr2)
_canmovedirs = [Direction.up,Direction.down]
} else {
var arr1 = []
var arr2 = []
if (Game.diff > 1) {
var w1 = Words.get_random(Game.diff)
var w2 = Words.get_random(Game.diff)
arr1 = Words.to_array(w1)
arr2 = Words.to_array(w2)
} else {
arr1.add(Letters.get_random())
arr2.add(Letters.get_random())
}
Direction.right.set_letters(arr1)
Direction.left.set_letters(arr2)
_canmovedirs = [Direction.right,Direction.left]
}
Words.clear_used()
Letters.clear_used()
}
get_tid(t,x,y) {
if (x == 0) {
if (y > 0) {
t = t | 0x00000001
} else {
t = t | 0x00000008
}
} else if (y == 0) {
if (x > 0) {
t = t | 0x00000002
} else {
t = t | 0x00000004
}
}
return t
}
draw() {
var rp = Game.lvl*30 * 8
var b = null
var nb = null
var pb = null
var tex = 16
var dx = 0
var dy = 0
var t_ = 0
for (i in 1..._body.count-1) {
pb = _body[i-1]
nb = _body[i+1]
b = _body[i]
tex = 32
t_ = 0
dx = b.x - pb.x
dy = b.y - pb.y
t_ = get_tid(t_,dx,dy)
dx = b.x - nb.x
dy = b.y - nb.y
t_ = get_tid(t_,dx,dy)
TIC.spr(tex+t_, b.x*8-rp, b.y*8, 0,1)
}
b = neck
var rot = 0
if (head.x < b.x) {
rot = 3
} else if (head.x > b.x) {
rot = 1
} else if (head.y > b.y) {
rot = 2
}
TIC.spr(tex+1, head.x*8-rp, head.y*8, 0,1,0,rot)
b = _body[1]
rot = 0
if (tail.x < b.x) {
rot = 3
} else if (tail.x > b.x) {
rot = 1
} else if (tail.y > b.y) {
rot = 2
}
TIC.spr(tex, tail.x*8-rp, tail.y*8, 0,1,0,rot)
var lt = ""
for (dir in _canmovedirs) {
if (dir.letters.count > 0) {
for (l in dir.letters) {
lt = lt + Letters.from_id(l)
}
if (dir.id == 4) {
TIC.print(lt, (head.x+dir.vec.x)*8+1-(dir.letters.count-1)*6-rp, (head.y+dir.vec.y)*8+2, 0,true)
TIC.print(lt, (head.x+dir.vec.x)*8+1-(dir.letters.count-1)*6-rp, (head.y+dir.vec.y)*8+1, 2,true)
} else {
TIC.print(lt, (head.x+dir.vec.x)*8+1-rp, (head.y+dir.vec.y)*8+2, 0,true)
TIC.print(lt, (head.x+dir.vec.x)*8+1-rp, (head.y+dir.vec.y)*8+1, 2,true)
}
}
lt = ""
}
}
got_food(d) {
if (head.x+d.x != Game.food.x || head.y+d.y != Game.food.y) return false
return true
}
move() {
if (!_can_switch) {
switch_dir()
_can_switch = true
}
var nx = head.x + _next_dir.vec.x
var ny = head.y + _next_dir.vec.y
if (TIC.mget(nx,ny) == 1) {
Game.fsm.set("gameover")
TIC.sfx(34,20,-1,3,15)
}
if (got_food(_next_dir.vec)) {
_body.add(BodyPart.new(0,Game.food.x,Game.food.y))
Game.spawn_food()
Game.add_score()
TIC.sfx(32,40,-1,3,15)
} else {
var t = tail
_body.removeAt(0)
t.x = head.x + _next_dir.vec.x
t.y = head.y + _next_dir.vec.y
_body.add(t)
}
}
turn(dir) {
_next_dir = dir
switch_dir()
}
update() {
}
onkeypressed(i) {
if (!_can_switch) return
var was_removed = false
for (dir in _canmovedirs) {
if (dir.match_letter(i)) {
TIC.sfx(33,40,-1,2,15)
dir.remove_letter(i)
if (dir.letters.count == 0) {
turn(dir)
return
}
was_removed = true
}
}
if (was_removed) return
_can_switch = false
for (dir in _canmovedirs) {
dir.set_letters([])
}
}
}
class FSM {
current { _current }
states { _states }
construct new() {
_states = {}
}
add(s) {
if (_states.containsKey(s.name)) {
Fiber.abort("state with name: %(s.name) already exists")
}
_states[s.name] = s
s.init()
}
remove(n) {
var s = _states[n]
if (s != null) {
if (_current == s) {
_current.onleave(null)
_current = null
}
_states.remove(n)
}
}
set(n) {set(n,null,null)}
set(n,ed) {set(n,ed,null)}
set(n,ed,ld) {
var s = _states[n]
if (s != null) {
if (_current != null) {
_current.onleave(ld)
}
s.onenter(ed)
_current = s
}
}
update(dt){
if (_current != null) {
_current.update(dt)
}
}
draw() {
if (_current != null) {
_current.draw()
}
}
}
class State {
name { _name }
construct new(n) {
_name = n
}
init() { }
onenter(d) { }
onleave(d) { }
update(dt) { }
draw() { }
}
class PlayState is State {
construct new() {
super("play")
}
init(){
_remap = Fn.new { |i, x, y|
if (i >=11 && i < 16) {
return 0
}
return i
}
}
onenter(d) {
_t = 0
Game.score = 0
Game.speed = 2
Game.snake = null
Game.food = null
var n = false
var lidx = Game.lvl*30
for (y in 0...17) {
for (x in lidx...lidx+30) {
n = TIC.mget(x,y)
// TIC.trace(n)
if (n == 12) {
Game.snake = Snake.new(0,x,y)
} else if (n == 13) {
TIC.trace("SPAWN")
Game.snake = Snake.new(1,x,y)
} else if (n == 14) {
Game.snake = Snake.new(2,x,y)
} else if (n == 15) {
Game.snake = Snake.new(3,x,y)
}
}
}
Game.spawn_food()
}
onleave(d) {
}
update(dt) {
if (TIC.keyp(27)) { // 0
Game.fsm.set("menu")
return
}
_t = _t+1
if (Game.snake != null) {
Game.snake.update()
if (_t%(60/Game.speed).floor == 0) {
Game.snake.move()
}
}
}
draw() {
TIC.map(Game.lvl * 30, 0, 30, 17, 0, 0, 0, 1, _remap)
if (Game.food != null) {
TIC.spr(2, Game.food.x*8-(Game.lvl*30*8), Game.food.y*8, 0)
}
if (Game.snake != null) {
Game.snake.draw()
}
TIC.print("SCORE: %(Game.score)", 190, 1, 2)
}
}
class GameOverState is State {
construct new() {
super("gameover")
}
onenter(d){
_texts = []
_complete = false
if (Game.score >= 20) {
_main = Text.new("LEVEL COMPLETE",64,28,1,2)
_complete = true
} else {
_main = Text.new("GAME OVER",64,28,1,2)
}
_score = Text.new("score: %(Game.score)",90,50,1,1)
_time = Text.new("time: %(0)",90,60,1,1)
_playtext = Text.new("press z to play next",62,100,1,1)
_menutext = Text.new("press x exit to menu",62,110,1,1)
_texts.add(_main)
_texts.add(_time)
_texts.add(_score)
_texts.add(_playtext)
_texts.add(_menutext)
}
update(dt) {
if(TIC.btnp(4)) { // z
if (_complete) {
Game.lvl = Game.lvl + 1
if(Game.lvl > 2){
Game.lvl = 0
Game.diff = Game.diff + 1
if (Game.diff > 5) {
Game.diff = 5
}
}
}
Game.fsm.set("play")
} else if(TIC.btnp(5)) { // z
Game.fsm.set("menu")
}
}
draw() {
for (t in _texts) {
t.draw()
}
}
}
class MenuState is State {
construct new() {
super("menu")
}
init(){
_sel = 0
_title = Text.new("TSNAKE",84,40,5,2)
_s = Text.new(">",78,80,2,1)
_p1 = Text.new("play",88,80,2,1)
_diff = Text.new("difficulty 1",88,90,2,1)
_lvltxt = Text.new("level %(Game.lvl)",88,100,2,1)
_mustxt = Text.new("music %(Game.music ? "on" : "off")",88,110,2,1)
}
onenter(d){
upd_diff()
upd_lvl()
upd_mus()
if (Game.music) {
// TIC.music(3)
}
}
upd_diff() {
_diff.text = "difficulty %(Game.diff)"
}
upd_lvl() {
_lvltxt.text = "level %(Game.lvl)"
}
upd_mus() {
_mustxt.text = "music %(Game.music ? "on" : "off")"
}
update(dt) {
if(TIC.keyp(50) || TIC.btnp(4)) { // z
Game.fsm.set("play")
}
if(TIC.btnp(0)) {
_sel = Maths.mod(_sel-1, 4)
_s.y = 80 + _sel*10
} else if(TIC.btnp(1)) {
_sel = (_sel+1)%4
_s.y = 80 + _sel*10
} else if(TIC.btnp(2)) {
if (_sel == 1) {
Game.diff = Game.diff - 1
if (Game.diff < 1) {
Game.diff = 1
}
upd_diff()
} else if (_sel == 2) {
Game.lvl = Game.lvl - 1
if (Game.lvl < 0) Game.lvl = 0
upd_lvl()
} else if (_sel == 3) {
Game.music = false
upd_mus()
}
} else if(TIC.btnp(3)) {
if (_sel == 1) {
Game.diff = Game.diff + 1
if (Game.diff > 5) {
Game.diff = 5
}
upd_diff()
} else if (_sel == 2) {
Game.lvl = Game.lvl + 1
if (Game.lvl > 2) Game.lvl = 2
upd_lvl()
} else if (_sel == 3) {
Game.music = true
upd_mus()
}
}
}
draw() {
_title.color = 3
_title.y = 41
_title.draw()
_title.color = 2
_title.y = 40
_title.draw()
_title.color = 1
_title.y = 39
_title.draw()
_s.draw()
_p1.draw()
_lvltxt.draw()
_diff.draw()
_mustxt.draw()
}
}
class Game is TIC {
static diff { __diff }
static diff=(v) { __diff=v }
static speed { __speed }
static speed=(v) { __speed=v }
static food { __food }
static food=(v) { __food=v }
static snake { __snake }
static snake=(v) { __snake=v }
static random { __rnd }
static timescale { __ts }
static timescale=(v) { __ts=v }
static fsm { __fsm }
static score { __score }
static score=(v) { __score=v }
static lvl { __lvl }
static lvl=(v) { __lvl=v }
static music { __music }
static music=(v) { __music=v }
construct new(){
Timer.init()
Key.init()
Words.init()
Letters.init()
Direction.init()
__diff = 1
__speed = 2
_t = 0
__lvl = 0
__score = 0
__ts = 1
__music = false
__rnd = Random.new()
_lastdir = 2
__fsm = FSM.new()
__fsm.add(GameOverState.new())
__fsm.add(MenuState.new())
__fsm.add(PlayState.new())
__fsm.set("menu")
}
static spawn_food() {
var np = Point.new(__rnd.int(1,28)+Game.lvl*30,__rnd.int(1,15))
if (TIC.mget(np.x, np.y) == 1) {
spawn_food()
return
}
for (b in __snake.body) {
if(b.x == np.x && b.y == np.y){
spawn_food()
return
}
}
__food = np
}
static add_score() {
__score = __score + 1
if (__score%5 == 0) {
__speed = __speed + 1
}
}
TIC(){
Key.update()
__fsm.update(_dt)
Timer.update(1/60)
TIC.cls(0)
__fsm.draw()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment