262 lines
8.8 KiB
Text
262 lines
8.8 KiB
Text
import "luxe: game" for Ready
|
|
import "luxe: assets" for Assets
|
|
import "luxe: input" for Input, Key, MouseButton
|
|
import "luxe: world" for World, Entity, Transform, Sprite, Values, Tags, Camera, Text
|
|
import "luxe: render" for Material
|
|
import "luxe: math" for Math
|
|
import "luxe: draw" for Draw
|
|
import "luxe: io" for IO
|
|
import "random" for Random
|
|
|
|
import "outline/app" for App
|
|
|
|
class Game is Ready {
|
|
|
|
construct ready() {
|
|
super("ready!")
|
|
|
|
app = App.new()
|
|
app.color = [0.12,0,0.12,1]
|
|
System.print("render size: %(app.width) x %(app.height) @ %(app.scale)x")
|
|
|
|
// game vars
|
|
_rand = Random.new()
|
|
_controls = "mouse" //"mouse" | "keyboard" | "controller"
|
|
|
|
// controls
|
|
if(_controls == "mouse") {
|
|
_reticule = Entity.create(app.world, "reticule")
|
|
var reticule_mat = Assets.material("material/reticule")
|
|
Sprite.create(_reticule, reticule_mat, 16, 16)
|
|
Transform.create(_reticule)
|
|
Input.set_mouse_capture(true)
|
|
}
|
|
|
|
// camera
|
|
_camera_scale = 2
|
|
_cam_size_x = (app.width / _camera_scale)
|
|
_cam_size_y = (app.height / _camera_scale)
|
|
Camera.ortho(app.camera, 0, _cam_size_y, _cam_size_x, 0, -10, 10)
|
|
|
|
// starfield
|
|
_stars = []
|
|
_starfield_context = Draw.create(World.render_set(app.world))
|
|
|
|
// player ship
|
|
_input_vec = []
|
|
_ship_speed = 20
|
|
_ship_acceleration = [0,0]
|
|
_ship_velocity = [0,0]
|
|
_ship_dampening = 0.97
|
|
|
|
// make things
|
|
create_startracker()
|
|
create_starfield()
|
|
create_ship()
|
|
create_asteroids()
|
|
create_ui_text()
|
|
} //ready
|
|
|
|
tick(delta) {
|
|
tick_ship(delta)
|
|
tick_camera(delta)
|
|
tick_startracker(delta)
|
|
tick_starfield(delta)
|
|
|
|
if(Input.key_state_released(Key.escape)) {
|
|
IO.shutdown()
|
|
}
|
|
} //tick
|
|
|
|
|
|
// CREATORS
|
|
///////////
|
|
create_ship() {
|
|
_ship = Entity.create(app.world, "ship")
|
|
var ship_mat = Assets.material("material/ship")
|
|
Sprite.create(_ship, ship_mat, 16, 32)
|
|
Transform.create(_ship)
|
|
Transform.set_pos(_ship, 0, 0, 0)
|
|
Transform.set_pos(app.camera, Transform.get_pos_x(_ship) - _cam_size_x / 2, Transform.get_pos_y(_ship) - _cam_size_y / 2)
|
|
} //create_ship
|
|
|
|
create_ui_text() {
|
|
_position_text = Entity.create(app.ui)
|
|
_mat_font = Assets.material("luxe: material/font")
|
|
Transform.create(_position_text)
|
|
Transform.set_pos(_position_text, app.width / 2 - 35, 20)
|
|
Text.create(_position_text, _mat_font, 32, "fonts/lato", [1,1,1,1])
|
|
} //create_ui_text
|
|
|
|
create_startracker() {
|
|
_startracker = Entity.create(app.world, "startracker")
|
|
Transform.create(_startracker)
|
|
Transform.set_pos(_startracker, 0, 0)
|
|
} //create_startracker
|
|
|
|
create_starfield() {
|
|
// each star needs [xpos, ypos, xsize, ysize, angle, alpha]
|
|
for(i in 0...500) {
|
|
var xpos = Transform.get_pos_x(_startracker) + (_rand.float(-250, 250))
|
|
var ypos = Transform.get_pos_y(_startracker) + (_rand.float(-250, 250))
|
|
var xsize = 2
|
|
var ysize = 2
|
|
var angle = 0
|
|
var alpha = _rand.float(0, 0.8)
|
|
_stars.add([xpos, ypos, xsize, ysize, angle, alpha])
|
|
Draw.quad(_starfield_context, xpos, ypos, -2, xsize * alpha, ysize * alpha, angle, [1,1,1,alpha])
|
|
}
|
|
Draw.commit(_starfield_context)
|
|
} //create_starfield
|
|
|
|
create_asteroids() {
|
|
for(i in 0...90) {
|
|
var asteroid = Entity.create(app.world, "asteroid")
|
|
var asteroid_mat = Assets.material("material/asteroid")
|
|
Sprite.create(asteroid, asteroid_mat, 8, 8)
|
|
Transform.create(asteroid)
|
|
var offsetx = _rand.float(-600, 600)
|
|
var offsety = _rand.float(-600, 600)
|
|
Transform.set_pos(asteroid, offsetx, offsety, -1)
|
|
}
|
|
} //create_asteroids
|
|
|
|
// TICKS
|
|
////////
|
|
tick_ship(delta) {
|
|
if(_controls == "keyboard") {
|
|
// WASD/arrows to move in directions. ship rotates to face movement direction
|
|
var input_vec = [get_axis("horizontal"), get_axis("vertical")]
|
|
Math.normalize2D(input_vec)
|
|
|
|
// 2d movement physics
|
|
_ship_acceleration = [input_vec.x * _ship_speed, input_vec.y * _ship_speed]
|
|
_ship_velocity = [_ship_velocity.x + (_ship_acceleration.x * delta), _ship_velocity.y + (_ship_acceleration.y * delta)]
|
|
_ship_velocity = [_ship_velocity.x * _ship_dampening, _ship_velocity.y * _ship_dampening]
|
|
|
|
// rotate ship in direction of movement, if input is detected (solves snap at vel=0)
|
|
if(input_vec.x != 0 || input_vec.y != 0) {
|
|
var ship_rotation = Math.atan2(_ship_velocity.y, _ship_velocity.x) + Math.radians(270)
|
|
Transform.set_euler_world(_ship, 0, 0, ship_rotation)
|
|
}
|
|
} //keyboard
|
|
|
|
if(_controls == "mouse") {
|
|
// ship rotates to face mouse pointer, right click adds thrust in facing direction.
|
|
// ship will slowly slow down, so you can keep traveling in one direction, but spin around to fire
|
|
// left click fires weapon
|
|
// todo: restrict cursor placement so it doesn't get within a certain distance of the ship
|
|
var mouse = Camera.screen_point_to_world(app.camera, Input.mouse_x(), Input.mouse_y())
|
|
Transform.set_pos(_reticule, mouse.x, mouse.y)
|
|
var ydiff = mouse.y - Transform.get_pos_y(_ship)
|
|
var xdiff = mouse.x - Transform.get_pos_x(_ship)
|
|
var rotation = Math.atan2(ydiff, xdiff) + Math.radians(270)
|
|
Transform.set_euler_world(_ship, 0, 0, rotation)
|
|
if(Input.mouse_state_down(MouseButton.right)) {
|
|
_ship_acceleration = [xdiff, ydiff]
|
|
Math.normalize2D(_ship_acceleration)
|
|
_ship_acceleration = [_ship_acceleration.x * 10, _ship_acceleration.y * 10]
|
|
_ship_velocity = [_ship_velocity.x + (_ship_acceleration.x * delta), _ship_velocity.y + (_ship_acceleration.y * delta)]
|
|
}
|
|
if(Input.mouse_state_down(MouseButton.left)) {
|
|
// shooting stuff
|
|
}
|
|
_ship_velocity = [_ship_velocity.x * _ship_dampening, _ship_velocity.y * _ship_dampening]
|
|
|
|
} //mouse
|
|
|
|
if(_controls == "controller") {
|
|
|
|
} //controller
|
|
|
|
// move ship
|
|
Transform.translate(_ship, _ship_velocity.x, _ship_velocity.y)
|
|
|
|
// update position text
|
|
var ship_pos_x_int = Math.floor_around_zero(Transform.get_pos_x(_ship))
|
|
var ship_pos_y_int = Math.floor_around_zero(Transform.get_pos_y(_ship))
|
|
Text.set_text(_position_text, "[%(ship_pos_x_int), %(ship_pos_y_int)]")
|
|
} //tick_ship
|
|
|
|
tick_camera(delta) {
|
|
// move the camera, with some lerp delay, following the ship
|
|
var shipx = Transform.get_pos_x(_ship)
|
|
var shipy = Transform.get_pos_y(_ship)
|
|
var camerax = Transform.get_pos_x(app.camera)
|
|
var cameray = Transform.get_pos_y(app.camera)
|
|
var interpolation = 0.8
|
|
var camera_interp_x = lerp(shipx - _cam_size_x / 2, camerax, interpolation)
|
|
var camera_interp_y = lerp(shipy - _cam_size_y / 2, cameray, interpolation)
|
|
Transform.set_pos(app.camera, camera_interp_x, camera_interp_y)
|
|
} //tick_camera
|
|
|
|
tick_startracker(delta) {
|
|
Transform.set_pos(_startracker, Transform.get_pos_x(app.camera) + _cam_size_x / 2, Transform.get_pos_y(app.camera) + _cam_size_y / 2)
|
|
// System.print("[%(Transform.get_pos_x(_startracker)),%(Transform.get_pos_y(_startracker))]")
|
|
} //tick_startracker
|
|
|
|
tick_starfield(delta) {
|
|
for(star in _stars) {
|
|
star[0] = star[0] - (_ship_velocity.x * (star[5] / 10))
|
|
star[1] = star[1] - (_ship_velocity.y * (star[5] / 10))
|
|
|
|
/*
|
|
// x pos reset
|
|
if(star[0] > Transform.get_pos_x(_ship) + _cam_size_x * _camera_scale) {
|
|
star[0] = Transform.get_pos_x(_ship) + -_cam_size_x * _camera_scale
|
|
}
|
|
if(star[0] < Transform.get_pos_x(_ship) + -_cam_size_x * _camera_scale) {
|
|
star[0] = Transform.get_pos_x(_ship) + _cam_size_x * _camera_scale
|
|
}
|
|
// y pos reset
|
|
if(star[1] > _cam_size_y * _camera_scale) {
|
|
star[1] = -_cam_size_y * _camera_scale
|
|
}
|
|
if(star[1] < -_cam_size_y * _camera_scale) {
|
|
star[1] = _cam_size_y * _camera_scale
|
|
}
|
|
*/
|
|
|
|
Draw.quad(_starfield_context, Transform.get_pos_x(_startracker) + star[0], Transform.get_pos_y(_startracker) + star[1], -2, star[2] * star[5], star[3] * star[5], star[4], [1,1,1,star[5]])
|
|
}
|
|
Draw.commit(_starfield_context)
|
|
} //tick_starfield
|
|
|
|
// MISC
|
|
///////
|
|
get_axis(axis) {
|
|
if(axis == "horizontal") {
|
|
var xaxis = 0
|
|
if(Input.key_state_down(Key.key_a) || Input.key_state_down(Key.left)) {
|
|
xaxis = xaxis - 1
|
|
}
|
|
if(Input.key_state_down(Key.key_d) || Input.key_state_down(Key.right)) {
|
|
xaxis = xaxis + 1
|
|
}
|
|
return xaxis
|
|
}
|
|
if(axis == "vertical") {
|
|
var yaxis = 0
|
|
if(Input.key_state_down(Key.key_w) || Input.key_state_down(Key.up)) {
|
|
yaxis = yaxis + 1
|
|
}
|
|
if(Input.key_state_down(Key.key_s) || Input.key_state_down(Key.down)) {
|
|
yaxis = yaxis - 1
|
|
}
|
|
return yaxis
|
|
}
|
|
} //get_axis
|
|
|
|
lerp(a, b, t) {
|
|
return a + t * (b - a)
|
|
} //lerp
|
|
|
|
destroy() {
|
|
System.print("unready!")
|
|
app.destroy()
|
|
} //destroy
|
|
|
|
app { _app }
|
|
app=(v) { _app=v }
|
|
|
|
} //Game
|