import "luxe: game" for Ready import "luxe: assets" for Assets import "luxe: input" for Input, Key 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() // camera _camera_scale = 1 _cam_offset_x = (app.width / _camera_scale) _cam_offset_y = (app.height / _camera_scale) Camera.ortho(app.camera, 0, _cam_offset_y, _cam_offset_x, 0, -5, 5) // starfield _stars = [] _starfield_context = Draw.create(World.render_set(app.world)) // player ship _input_vec = [] _ship_rotation = 0 _ship_speed = 40 _ship_acceleration_x = 0 _ship_acceleration_y = 0 _ship_velocity_x = 0 _ship_velocity_y = 0 _ship_dampening = 0.85 // make things create_ship() Transform.set_pos(app.camera, Transform.get_pos_x(_ship) - _cam_offset_x / 2, Transform.get_pos_y(_ship) - _cam_offset_y / 2) create_ui_text() create_startracker() create_starfield() Draw.commit(_starfield_context) } //ready tick(delta) { tick_ship(delta) tick_camera(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) } //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() { _star_tracker = Entity.create(app.world, "star_tracker") Transform.create(_star_tracker) Transform.set_pos(_star_tracker, Transform.get_pos_x(_ship), Transform.get_pos_y(_ship), Transform.get_pos_z(_ship)) } //create_startracker create_starfield() { for(i in 0...5000) { var xpos = _rand.float() * 1000 - 500 var ypos = _rand.float() * 1000 - 500 Draw.quad(_starfield_context, xpos-1, ypos, -1, 3, 1, 0, [1,1,1,1]) Draw.quad(_starfield_context, xpos, ypos-1, -1, 1, 3, 0, [1,1,1,1]) } } //create_starfield2 // UPDATERS /////////// tick_ship(delta) { var input_vec = [get_axis("horizontal"), get_axis("vertical")] Math.normalize2D(input_vec) // 2d movement physics _ship_acceleration_x = input_vec.x * _ship_speed _ship_acceleration_y = input_vec.y * _ship_speed _ship_velocity_x = _ship_velocity_x + (_ship_acceleration_x * delta) _ship_velocity_y = _ship_velocity_y + (_ship_acceleration_y * delta) _ship_velocity_x = _ship_velocity_x * _ship_dampening _ship_velocity_y = _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) { _ship_rotation = Math.atan2(_ship_velocity_y, _ship_velocity_x) + Math.radians(270) Transform.set_euler_world(_ship, 0, 0, _ship_rotation) } // 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, along with 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_offset_x / 2, camerax, interpolation) var camera_interp_y = lerp(shipy - _cam_offset_y / 2, cameray, interpolation) Transform.set_pos(app.camera, camera_interp_x, camera_interp_y) } //tick_camera tick_starfield(delta) { //todo: 20191130 - found an interesting bug, where if you (while going super fast) travel out too far, and return to [0,0], the stars will be slightly misaligned. must have something to do with a floating point error while moving the stars around. Went to 25,000 out and saw a slight misalign // to fix, can make scrolling more accurate somehow, maybe track a stars movement and see where it gets it's error. probably when having them switch sides // another option is to restrict how far out the player can travel from [0,0], either with a hard limit, or some gameplay thing that makes them stay close to base Transform.set_pos(_star_tracker, Transform.get_pos_x(app.camera) + _cam_offset_x, Transform.get_pos_y(app.camera) + _cam_offset_y, -1) // loop through stars[] for(star in _stars) { Transform.set_pos_x(star, Transform.get_pos_x(star) + -_ship_velocity_x * (Sprite.get_alpha(star) * 0.5)) Transform.set_pos_y(star, Transform.get_pos_y(star) + -_ship_velocity_y * (Sprite.get_alpha(star) * 0.5)) // x pos reset if(Transform.get_pos_x(star) > _cam_offset_x * _camera_scale) { Transform.set_pos_x(star, -_cam_offset_x * _camera_scale) } if(Transform.get_pos_x(star) < -_cam_offset_x * _camera_scale) { Transform.set_pos_x(star, _cam_offset_x * _camera_scale) } // y pos reset if(Transform.get_pos_y(star) > _cam_offset_y * _camera_scale) { Transform.set_pos_y(star, -_cam_offset_y * _camera_scale) } if(Transform.get_pos_y(star) < -_cam_offset_y * _camera_scale) { Transform.set_pos_y(star, _cam_offset_y * _camera_scale) } } } //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