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