Created
March 20, 2021 18:29
-
-
Save weshardee/c04693dae3c79ffb8b0cfbeb49a52eff to your computer and use it in GitHub Desktop.
testing odin language server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package test | |
import "core:math/linalg" | |
import "core:math" | |
import "core:fmt" | |
import "core:container" | |
import "src:lib" | |
import "src:lib/core" | |
import "src:lib/draw" | |
import "src:lib/debug" | |
import "src:lib/input" | |
import "src:lib/shapes" | |
V2 :: core.V2; | |
V3 :: core.V3; | |
M4 :: core.M4; | |
VIEW_W :: 256; | |
VIEW_H :: 240; | |
PIXEL_SCALE :: 3; | |
INVERSE_SQRT_TWO :: 1 / math.SQRT_TWO; | |
PIG_RGBA :: #load("res/pig.rgba"); | |
PIG_W :: 96; | |
PIG_H :: 24; | |
PIG_FRAME_W :: PIG_W / 3; | |
PIG_RADIUS :: 8; | |
PIG_Y_OFFSET :: 8; | |
LAUNCH_BUTTON_RGBA :: #load("res/LaunchButton.rgba"); | |
LAUNCH_BUTTON_W :: 48; | |
LAUNCH_BUTTON_H :: 16; | |
LAUNCH_BUTTON_SIZE :: V2{LAUNCH_BUTTON_W, LAUNCH_BUTTON_H}; | |
ROCKET_SHIP_RGBA :: #load("res/RocketShip.rgba"); | |
ROCKET_SHIP_W :: 64; | |
ROCKET_SHIP_H :: 96; | |
ROCKET_SHIP_OFFSET_X :: 32; | |
ROCKET_SHIP_LAUNCH_RGBA :: #load("res/RocketShipLaunch.rgba"); | |
ROCKET_SHIP_LAUNCH_W :: 64; | |
ROCKET_SHIP_LAUNCH_H :: 128; | |
ROCKET_SHIP_LAUNCH_OFFSET_Y :: ROCKET_SHIP_LAUNCH_H - ROCKET_SHIP_H; | |
BTN_PAD :: 10; | |
PIG_MOVE_SPEED :: 1; | |
PIG_ANIM_SPEED :: 0.1; | |
MAX_APPLES :: 128; | |
APPLE_RGBA :: #load("res/apple.rgba"); | |
APPLE_W :: 10; | |
APPLE_H :: 12; | |
APPLE_HALF_W :: APPLE_W / 2; | |
APPLE_HALF_H :: APPLE_H / 2; | |
APPLE_RADIUS :: 5; | |
Pig :: struct { | |
img_id : int, | |
pos: V3, | |
transform : M4, | |
frames : [3]core.Quad_Corners, | |
anim : f32, | |
frame_i : int, | |
state : Pig_State, | |
facing_x : f32, | |
area : shapes.Circle, | |
} | |
Apple :: struct { | |
pos : V3, | |
transform : M4, | |
area : shapes.Circle, | |
eaten : bool, | |
}; | |
Pig_State :: enum { | |
Idle, | |
Moving, | |
} | |
State :: struct { | |
tick : f32, | |
view_bottom_right : V3, | |
launch_btn_id : int, | |
launch_btn_corners : core.Quad_Corners, | |
launch_btn_translate : V3, | |
launch_btn_transform : M4, | |
rocket_img_id : int, | |
rocket_launch_img_id : int, | |
rocket_corners : core.Quad_Corners, | |
rocket_launch_corners : core.Quad_Corners, | |
rocket_pos : V3, | |
rocket_vel : V2, | |
rocket_transform : M4, | |
pig : Pig, | |
apple_img_id : int, | |
apple_corners : core.Quad_Corners, | |
apples : container.Small_Array(MAX_APPLES, Apple), | |
score : int, | |
launched : bool, | |
pos : V2, | |
}; | |
state :: proc() -> ^State { | |
return cast(^State)lib.ctx().game_state.data; | |
} | |
@export | |
conf :: proc(conf: ^core.Conf) { | |
conf.title = "Heartbeast 1-bit"; | |
conf.width = VIEW_W * PIXEL_SCALE; | |
conf.height = VIEW_H * PIXEL_SCALE; | |
} | |
@export | |
load :: proc() { | |
lib.init_state(State); | |
ctx := lib.ctx(); | |
state := state(); | |
state.launch_btn_id = ctx.register_img( | |
raw_data(LAUNCH_BUTTON_RGBA), LAUNCH_BUTTON_W, LAUNCH_BUTTON_H, 4); | |
state.launch_btn_corners = draw.corners(0, 0, LAUNCH_BUTTON_W, LAUNCH_BUTTON_H); | |
state.rocket_img_id = lib.ctx().register_img( | |
raw_data(ROCKET_SHIP_RGBA), ROCKET_SHIP_W, ROCKET_SHIP_H, 4); | |
state.rocket_corners = draw.corners( | |
-ROCKET_SHIP_OFFSET_X, | |
0, | |
ROCKET_SHIP_W - ROCKET_SHIP_OFFSET_X, | |
ROCKET_SHIP_H); | |
state.rocket_launch_img_id = ctx.register_img( | |
raw_data(ROCKET_SHIP_LAUNCH_RGBA), ROCKET_SHIP_LAUNCH_W, ROCKET_SHIP_LAUNCH_H, 4); | |
state.rocket_launch_corners = draw.corners( | |
-ROCKET_SHIP_OFFSET_X, | |
-ROCKET_SHIP_LAUNCH_OFFSET_Y, | |
ROCKET_SHIP_LAUNCH_W - ROCKET_SHIP_OFFSET_X, | |
ROCKET_SHIP_H); | |
{ | |
pig_frame_half_w : f32 = PIG_FRAME_W / 2; | |
pig_frame_half_h : f32 = PIG_H / 2; | |
state.pig.img_id = ctx.register_img( | |
raw_data(PIG_RGBA), PIG_W, PIG_H, 4); | |
x0 := -pig_frame_half_w; | |
x1 := pig_frame_half_w; | |
y0 : f32 = -PIG_Y_OFFSET; | |
y1 := y0 + PIG_H; | |
u_increment : f32 = 1.0/3.0; | |
u0 : f32 = 0; | |
u1 : f32 = u_increment; | |
for i in 0..2 { | |
state.pig.frames[i] = draw.corners( | |
x0=x0, x1=x1, y0=y0, y1=y1, u0=u0, u1=u1, v0=0, v1=1); | |
u0 = u1; | |
u1 += u_increment; | |
} | |
state.pig.facing_x = 1; | |
state.pig.area.r = PIG_RADIUS; | |
} | |
state.rocket_pos.y = -160; | |
state.apple_img_id = ctx.register_img( | |
raw_data(APPLE_RGBA), APPLE_W, APPLE_H, 4); | |
state.apple_corners = draw.corners( | |
-APPLE_HALF_W, -APPLE_HALF_H, APPLE_HALF_W, APPLE_HALF_H); | |
add_apple(V3{10, 10, 0}); | |
add_apple(V3{20, 10, 0}); | |
add_apple(V3{20, -10, 0}); | |
} | |
@export | |
update :: proc(dt: f32) { | |
state := state(); | |
state.tick += 1; | |
lib.set_view_2d(240, 160, .MAIN); | |
win_w := f32(lib.ctx().window.width); | |
win_h := f32(lib.ctx().window.height); | |
state.view_bottom_right = core.unproject(V3{win_w, win_h, 0}); | |
state.launch_btn_translate.x = state.view_bottom_right.x - LAUNCH_BUTTON_W - BTN_PAD; | |
state.launch_btn_translate.y = state.view_bottom_right.y + BTN_PAD + 0.5; | |
state.launch_btn_transform = linalg.matrix4_translate(state.launch_btn_translate); | |
if input.was_pressed(input.Mouse_Button.LEFT) { | |
mouse_pos := input.mouse_pos(); | |
launch_btn_shape := shapes.Rect{ | |
min_x = state.launch_btn_translate.x, | |
min_y = state.launch_btn_translate.y, | |
max_x = state.launch_btn_translate.x + LAUNCH_BUTTON_W, | |
max_y = state.launch_btn_translate.y + LAUNCH_BUTTON_H, | |
}; | |
if (shapes.test_overlap(V2{mouse_pos.x, mouse_pos.y}, launch_btn_shape)) { | |
state.launched = true; | |
} | |
} | |
if state.launched { | |
state.rocket_vel.y += 0.05; | |
state.rocket_pos.y += state.rocket_vel.y; | |
} | |
rocket_pos_floored := linalg.round(state.rocket_pos); | |
state.rocket_transform = linalg.matrix4_translate(rocket_pos_floored); | |
lib.prune(&state.apples, proc(apple: ^Apple) -> bool { | |
return apple.eaten; | |
}); | |
input_dir := get_input_dir(); | |
state.pig.pos.x += input_dir.x * PIG_MOVE_SPEED; | |
state.pig.pos.y += input_dir.y * PIG_MOVE_SPEED; | |
has_input := input_dir.x != 0 || input_dir.y != 0; | |
if input_dir.x != 0 { | |
state.pig.facing_x = input_dir.x > 0 ? 1 : -1; | |
} | |
switch state.pig.state { | |
case .Idle: { | |
if has_input { | |
state.pig.anim = 1; | |
state.pig.state = .Moving; | |
} | |
} | |
case .Moving: { | |
if !has_input { | |
state.pig.state = .Idle; | |
state.pig.anim = 0; | |
} | |
else { | |
state.pig.anim += PIG_ANIM_SPEED; | |
if state.pig.anim >= 3 do state.pig.anim -= 3; | |
} | |
} | |
} | |
state.pig.frame_i = cast(int)math.floor(state.pig.anim); | |
state.pig.transform = linalg.mul( | |
linalg.matrix4_translate(linalg.round(state.pig.pos)), | |
linalg.matrix4_scale(core.V3{state.pig.facing_x, 1, 1}), | |
); | |
state.pig.area.center = V2{state.pig.pos.x, state.pig.pos.y}; | |
lib.each(&state.apples, check_if_eaten); | |
} | |
@export | |
draw :: proc() { | |
state := state(); | |
draw.img( | |
state.pig.img_id, | |
state.pig.frames[state.pig.frame_i], | |
state.pig.transform, | |
); | |
pig_pos_v2 := V2{state.pig.pos.x, state.pig.pos.y}; | |
draw.circ({ | |
center = pig_pos_v2, | |
r = PIG_RADIUS, | |
}, draw.RED); | |
draw.point(pig_pos_v2, draw.RED); | |
draw.img( | |
state.launch_btn_id, | |
state.launch_btn_corners, | |
state.launch_btn_transform, | |
); | |
if state.launched { | |
draw.img( | |
state.rocket_launch_img_id, | |
state.rocket_launch_corners, | |
state.rocket_transform, | |
); | |
} | |
else { | |
draw.img( | |
state.rocket_img_id, | |
state.rocket_corners, | |
state.rocket_transform, | |
); | |
} | |
lib.each(&state.apples, draw_apple); | |
} | |
get_input_dir :: proc() -> V2 { | |
if input.use_controller() { | |
return input.l_stick(); | |
} | |
else { | |
x, y : f32; | |
if input.is_down(input.Key_Code.W) do y += 1; | |
if input.is_down(input.Key_Code.A) do x -= 1; | |
if input.is_down(input.Key_Code.S) do y -= 1; | |
if input.is_down(input.Key_Code.D) do x += 1; | |
if x != 0 && y != 0 { | |
x *= INVERSE_SQRT_TWO; | |
y *= INVERSE_SQRT_TWO; | |
} | |
return V2{x, y}; | |
} | |
} | |
add_apple :: proc(pos: V3) { | |
state := state(); | |
transform := linalg.matrix4_translate(V3{pos.x, pos.y, 0}); | |
container.small_array_push(&state.apples, Apple { | |
pos = pos, | |
transform = transform, | |
area = shapes.Circle{center = V2{pos.x, pos.y}, r = APPLE_RADIUS}, | |
}); | |
} | |
draw_apple :: proc(apple: ^Apple) { | |
state := state(); | |
draw.img( | |
state.apple_img_id, | |
state.apple_corners, | |
apple.transform, | |
); | |
draw.circ({ | |
center = V2{apple.pos.x, apple.pos.y}, | |
r = APPLE_RADIUS, | |
}, draw.RED); | |
} | |
check_if_eaten :: proc(apple: ^Apple) { | |
state := state(); | |
if apple.eaten do return; | |
if shapes.test_overlap(apple.area, state.pig.area) { | |
apple.eaten = true; | |
state.score += 1; | |
// TODO play a sound | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment