majorjam-4/cart.wren

386 lines
8.1 KiB
Plaintext

// title: game title
// author: Fabien Freling
// desc: (Major Jam 8)
// script: wren
import "random" for Random
var W = 240
var H = 136
var R = Random.new()
class Star {
construct new(x, y, size, scrollSpeed, color) {
_x = x
_y = y
_size = size
_scrollSpeed = scrollSpeed
_color = color
}
update() {
_x = _x - _scrollSpeed
}
draw() {
TIC.circ(_x, _y, _size, _color)
}
expired {
_x + _size < 0
}
}
class Bullet {
construct new(x, y) {
_x = x
_y = y
_w = 3
_h = 1
_speed = 5
}
x { _x }
y { _y }
w { _w }
h { _h }
update() {
_x = _x + _speed
}
draw() {
TIC.rect(_x, _y, _w, _h, 4)
}
expired {
_x > W
}
}
class Enemy {
construct new(x, y) {
_x = x
_y = y
_w = 8
_h = 8
_speed = 1
_alive = true
}
x { _x }
y { _y }
w { _w }
h { _h }
expired { !_alive }
update() {
_x = _x - _speed
if (_x < -_w) {
_alive = false
}
}
draw() {
TIC.spr(258, _x - _w / 2, _y - _h / 2, 0)
}
hit() {
_alive = false
}
}
class Ship {
construct new(x, y) {
_x = x
_y = y
_speed = 1
_bullets = []
}
bullets { _bullets }
update() {
if (TIC.btn(0)) {
_y = _y - _speed
}
if (TIC.btn(1)) {
_y = _y + _speed
}
if (TIC.btn(2)) {
_x = _x - _speed
}
if (TIC.btn(3)) {
_x = _x + _speed
}
_x.clamp(0, W)
_y.clamp(0, H)
if (TIC.btnp(4, 5, 10)) {
shoot()
}
for (b in _bullets) {
b.update()
}
while (_bullets.count > 0 && _bullets[0].expired) {
_bullets.removeAt(0)
}
}
draw() {
TIC.spr(256, _x, _y, 0, 1, 0, 0, 2, 2)
for (b in _bullets) {
b.draw()
}
}
shoot() {
_bullets.add(Bullet.new(_x + 8, _y + 8))
}
}
class Explosion {
construct new(x, y) {
System.print("explosion at %(x), %(y)")
_x = x
_y = y
_countdown = 30
}
expired { _countdown < 0 }
update() {
//System.print("explosion countdown %(_countdown)")
_countdown = _countdown - 1
}
draw() {
var size = 10
TIC.circ(_x - size / 2, _y - size / 2, size, 2)
}
}
class World {
construct new() {
_t = 0
_stars = []
_enemies = []
_vfx = []
_player = Ship.new(W / 2, H / 2)
_world_x = 0
_world_y = 0
_world_scroll_speed = 60 / 2
// init background
for (i in 0..W) {
update()
}
_remap = Fn.new {|tile, x, y|
if (tile == 33) {
this.spawn(tile, x, y)
return 0
}
return tile
}
}
collect(list) {
var i = 0
while (i < list.count) {
//System.print("%(list[i])")
if (list[i].expired) {
//System.print("remove element from list")
list.removeAt(i)
} else {
i = i + 1
}
}
}
spawn(tile, x, y) {
_enemies.add(Enemy.new(x * 4, y * 4))
TIC.mset(x, y, 0)
}
update() {
_player.update()
for (e in _enemies) {
e.update()
}
for (s in _stars) {
s.update()
}
for (v in _vfx) {
v.update()
}
// Collect
while (_stars.count > 0 && _stars[0].expired) {
_stars.removeAt(0)
}
collect(_enemies)
collect(_vfx)
// small stars
if (_t % 30 == 0) {
_stars.add(Star.new(W, R.int(0,H), 1, 1, 12))
}
// medium stars
var width = 10
var spaceBetween = width * 10
var speed = 0.1
var mediumTick = (spaceBetween + width) / speed
if (_t % mediumTick == 0) {
_stars.add(Star.new(W, R.int(0,H), width, speed, 13))
}
_t = _t + 1
if (_t % _world_scroll_speed == 0) {
_world_x = _world_x + 1
}
// Collisions
var i = 0
while (i < _player.bullets.count) {
var b = _player.bullets[i]
var touched = false
for (e in _enemies) {
if (collide(b.x, b.y, b.w, b.h, e.x, e.y, e.w, e.h)) {
_player.bullets.removeAt(i)
e.hit()
_vfx.add(Explosion.new(e.x + e.w / 2, e.y + e.h / 2))
touched = true
break
}
}
if (!touched) {
i = i + 1
}
}
}
collide(x1, y1, w1, h1, x2, y2, w2, h2) {
// [x1] [x2]
if (x1 + w1 < x2) {
return false
}
// [x2] [x1]
if (x1 > x2 + w2) {
return false
}
// [y1]
// [y2]
if (y1 + h2 < y2) {
return false
}
// [y2]
// [y1]
if (y1 > y2 + h2) {
return false
}
return true
}
draw() {
for (s in _stars) {
s.draw()
}
for (v in _vfx) {
v.draw()
}
var sx = (_t % _world_scroll_speed) / (_world_scroll_speed / 8)
TIC.map(_world_x, _world_y, 30 + 1, 17 + 1, -sx, 0, 0, 1, _remap)
for (e in _enemies) {
e.draw()
}
_player.draw()
}
}
class Game is TIC{
state { _state }
static start { "start" }
static game { "game" }
construct new() {
_t=0
_x=96
_y=24
_state = Game.start
_world = World.new()
}
TIC() {
update()
draw()
_t=_t+1
}
update() {
_world.update()
}
draw() {
TIC.cls(0)
_world.draw()
}
}
// <TILES>
// 001:eccccccccc888888caaaaaaaca888888cacccccccacc0ccccacc0ccccacc0ccc
// 002:ccccceee8888cceeaaaa0cee888a0ceeccca0ccc0cca0c0c0cca0c0c0cca0c0c
// 003:eccccccccc888888caaaaaaaca888888cacccccccacccccccacc0ccccacc0ccc
// 004:ccccceee8888cceeaaaa0cee888a0ceeccca0cccccca0c0c0cca0c0c0cca0c0c
// 005:2222222223312331231123112111211122222222233123312311231121112111
// 017:cacccccccaaaaaaacaaacaaacaaaaccccaaaaaaac8888888cc000cccecccccec
// 018:ccca00ccaaaa0ccecaaa0ceeaaaa0ceeaaaa0cee8888ccee000cceeecccceeee
// 019:cacccccccaaaaaaacaaacaaacaaaaccccaaaaaaac8888888cc000cccecccccec
// 020:ccca00ccaaaa0ccecaaa0ceeaaaa0ceeaaaa0cee8888ccee000cceeecccceeee
// 033:0000000000000000000000000002200000022000000000000000000000000000
// 034:0000000000000000000000000003300000033000000000000000000000000000
// </TILES>
// <SPRITES>
// 000:00000000000000000ccc000000eccccc00eeeeee4ddddddd4cccccdd43ddddcc
// 001:00000000000000000000000000000000ee990000ddaa9900ddaaaa90ccaaaaa9
// 002:2000000202333320032222300320023003200230032222300233332020000002
// 016:43dddddd4ddddddd4eeeeeee0ccccccc00000000000000000000000000000000
// 017:ddccccccddddddd0eeeeee000000000000000000000000000000000000000000
// </SPRITES>
// <MAP>
// 006:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 014:000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000500000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 015:000000000000000000000000000000000000000000000000000000000000000000000000505050000000000050505000000000005050500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// 016:000000000000000000000000000000000000000000000000000000000000505050505050505050505050505050505050505050505050505050505050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
// </MAP>
// <WAVES>
// 000:00000000ffffffff00000000ffffffff
// 001:0123456789abcdeffedcba9876543210
// 002:0123456789abcdef0123456789abcdef
// </WAVES>
// <SFX>
// 000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304000000000
// </SFX>
// <PALETTE>
// 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
// </PALETTE>