From 01d49ff7246c98b11d3e005dd9fe5dc81176a3c4 Mon Sep 17 00:00:00 2001 From: me Date: Sat, 20 Dec 2025 22:31:46 +0200 Subject: [PATCH] color game --- colorgame.ayin | 61 +++++++++++++++++++++++++----- src/interpret/interpret.rs | 12 +++++- src/interpret/types.rs | 11 ++++-- src/main.rs | 7 +++- src/runtime/primitive_functions.rs | 37 +++++++++++++++++- src/runtime/types.rs | 6 +-- 6 files changed, 112 insertions(+), 22 deletions(-) diff --git a/colorgame.ayin b/colorgame.ayin index 208f0fb..eeeb593 100644 --- a/colorgame.ayin +++ b/colorgame.ayin @@ -1,5 +1,3 @@ -let speed = 100 - let setup = fn() { return { .color: { @@ -8,16 +6,18 @@ let setup = fn() { .b: random_u8(), }, .rect: { + .speed: 100, .dimensions: { - .x: 100, - .y: 100, - .w: 100, - .h: 100, + .x: 50, + .y: 50, + .w: 300 - 50, + .h: 300 - 50, }, .color: { .r: random_u8(), .g: random_u8(), .b: random_u8(), + .speed: 150, }, }, }; @@ -25,19 +25,60 @@ let setup = fn() { let update = fn(state, input) { let delta = get_frame_time(); + + let dpad_x = if input.gamepad1.dpad.right { 1 } else { 0 } + if input.gamepad1.dpad.left { -1 } else { 0 }; + let dpad_y = if input.gamepad1.dpad.down { 1 } else { 0 } + if input.gamepad1.dpad.up { -1 } else { 0 }; + + # let movement = { + # .x: input.gamepad1.sticks.left.x + dpad_x, + # .y: input.gamepad1.sticks.left.y + dpad_y, + # }; let movement = { - .x: input.gamepad1.sticks.left.x, - .y: input.gamepad1.sticks.left.y, + .x: dpad_x, + .y: dpad_y, }; state.rect.dimensions.x = - state.rect.dimensions.x + (delta * speed * movement.x); + state.rect.dimensions.x + (delta * state.rect.speed * movement.x); state.rect.dimensions.y = - state.rect.dimensions.y + (delta * speed * movement.y); + state.rect.dimensions.y + (delta * state.rect.speed * movement.y); + + let color = { + .r: state.rect.color.r + (input.gamepad1.sticks.right.x * delta * state.rect.color.speed), + .g: state.rect.color.g + ((0 - input.gamepad1.sticks.right.y) * delta * state.rect.color.speed), + .b: state.rect.color.b + ((0 - input.gamepad1.sticks.left.y) * delta * state.rect.color.speed), + }; + + state.rect.color.r = if ((0 <= color.r) && (color.r <= 255)) { color.r } else { if color.r < 0 { 0 } else { 255 } }; + state.rect.color.g = if ((0 <= color.g) && (color.g <= 255)) { color.g } else { if color.g < 0 { 0 } else { 255 } }; + state.rect.color.b = if ((0 <= color.b) && (color.b <= 255)) { color.b } else { if color.b < 0 { 0 } else { 255 } }; return state; } let draw = fn(state) { frame_clear(state.color.r, state.color.g, state.color.b); draw_rectangle(state.rect.dimensions, state.rect.color); + + let mut count = 0; + let r_diff = state.color.r - state.rect.color.r; + let g_diff = state.color.g - state.rect.color.g; + let b_diff = state.color.b - state.rect.color.b; + let epsilon = 2; + + if ((0 - epsilon) < r_diff) && (r_diff < epsilon) { count = count + 1; }; + if ((0 - epsilon) < g_diff) && (g_diff < epsilon) { count = count + 1; }; + if ((0 - epsilon) < b_diff) && (b_diff < epsilon) { count = count + 1; }; + + if count == 0 { + draw_text("Match the colors", 200, 200, 50, { .r: 255, .g: 255, .b: 255 }); + }; + if count == 1 { + draw_text("Close", 200, 200, 50, { .r: 255, .g: 255, .b: 255 }); + }; + if count == 2 { + draw_text("Closer!!", 200, 200, 50, { .r: 255, .g: 255, .b: 255 }); + }; + if count == 3 { + draw_text("Great Job!", 200, 200, 50, { .r: 255, .g: 255, .b: 255 }); + }; } diff --git a/src/interpret/interpret.rs b/src/interpret/interpret.rs index 209e3b5..fa34547 100644 --- a/src/interpret/interpret.rs +++ b/src/interpret/interpret.rs @@ -204,7 +204,11 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result Err(Error::NotAReference(v.clone(), Backtrace::capture())), + v => Err(Error::NotAReference( + *lhs.clone(), + v.clone(), + Backtrace::capture(), + )), }, ast::Op::Calc(cop) => { let lhs = eval_expr(expr_env, state, lhs)?; @@ -378,7 +382,11 @@ fn eval_expr_shallow( let result = expr_env.get(&var)?; match result { ast::Value::Ref(_) => Ok(result.clone()), - v => Err(Error::NotAReference(v.clone(), Backtrace::capture())), + v => Err(Error::NotAReference( + expr.clone(), + v.clone(), + Backtrace::capture(), + )), } } ast::Expr::Access { expr, field } => match eval_expr(expr_env, state, expr)? { diff --git a/src/interpret/types.rs b/src/interpret/types.rs index b7eefb1..b6f80f6 100644 --- a/src/interpret/types.rs +++ b/src/interpret/types.rs @@ -15,7 +15,7 @@ pub enum Error { LastStatementNotAnExpr(Backtrace), NotAFunction(ast::Expr, Backtrace), NotARecord(ast::Value, Backtrace), - NotAReference(ast::Value, Backtrace), + NotAReference(ast::Expr, ast::Value, Backtrace), NotABoolean(ast::Value, Backtrace), OpError(ast::Value, ast::Op, ast::Value, Backtrace), MigrationError(ast::Value, String, Backtrace), @@ -33,7 +33,9 @@ impl PartialEq for Error { (Error::NotAFunction(a1, _), Error::NotAFunction(a2, _)) => a1 == a2, (Error::NotARecord(a1, _), Error::NotARecord(a2, _)) => a1 == a2, - (Error::NotAReference(a1, _), Error::NotAReference(a2, _)) => a1 == a2, + (Error::NotAReference(a1, b1, _), Error::NotAReference(a2, b2, _)) => { + a1 == a2 && b1 == b2 + } (Error::NotABoolean(a1, _), Error::NotABoolean(a2, _)) => a1 == a2, (Error::MigrationError(a1, b1, _), Error::MigrationError(a2, b2, _)) => { a1 == a2 && b1 == b2 @@ -62,7 +64,10 @@ impl std::fmt::Display for Error { } Error::NotAFunction(a, b) => write!(f, "Not a function {a:?}\n{b}"), Error::NotARecord(a, b) => write!(f, "Not a record {a:?}\n{b}"), - Error::NotAReference(a, b) => write!(f, "Not a reference {a:?}\n{b}"), + Error::NotAReference(a, b, c) => write!( + f, + "Not a reference. Are you missing a `mut`? {a:?} {b:?}\n{c}" + ), Error::NotABoolean(a, b) => write!(f, "Not a boolean {a:?}\n{b}"), Error::ArgumentsMismatch(a) => write!(f, "Arguments mismatch\n{a}"), Error::OpError(a, b, c, d) => write!(f, "Op Error {a:?} {b:?} {c:?}\n{d}"), diff --git a/src/main.rs b/src/main.rs index 71ed8dc..4899163 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,8 @@ fn window_conf() -> Conf { Conf { window_title: "Ayin".to_owned(), fullscreen: false, - window_width: SCREEN_WIDTH, - window_height: SCREEN_HEIGHT, + window_width: SCREEN_WIDTH as i32, + window_height: SCREEN_HEIGHT as i32, ..Default::default() } } @@ -15,6 +15,9 @@ fn window_conf() -> Conf { async fn main() { env_logger::init(); info!("Hello, 👁️‍🗨️!"); + if screen_width() < SCREEN_WIDTH { + request_new_screen_size(SCREEN_WIDTH as f32, SCREEN_HEIGHT as f32); + } let args: Vec = std::env::args().collect(); let file = args[1].clone(); diff --git a/src/runtime/primitive_functions.rs b/src/runtime/primitive_functions.rs index 23bb32e..b42dbdf 100644 --- a/src/runtime/primitive_functions.rs +++ b/src/runtime/primitive_functions.rs @@ -1,14 +1,16 @@ +use macroquad::prelude as mq; use macroquad::time::get_frame_time; use rand::prelude::*; use crate::ast; use crate::interpret::PrimitiveFuncs; -use macroquad::prelude as mq; +use crate::runtime::types::SCALE; pub fn primitive_funcs() -> PrimitiveFuncs { PrimitiveFuncs::new(vec![ ("frame_clear", clear), ("draw_rectangle", draw_rectangle), + ("draw_text", draw_text), ("get_frame_time", frame_time), ("random_u8", random_u8), ]) @@ -58,7 +60,31 @@ fn draw_rectangle(args: Vec) -> ast::Value { } _ => todo!(), }; - mq::draw_rectangle(rectangle.x, rectangle.y, rectangle.w, rectangle.h, color); + mq::draw_rectangle( + rectangle.x * SCALE as f32, + rectangle.y * SCALE as f32, + rectangle.w * SCALE as f32, + rectangle.h * SCALE as f32, + color, + ); + ast::UNIT_VALUE +} + +fn draw_text(args: Vec) -> ast::Value { + let text = to_string(args.get(0)); + let x = to_f32(args.get(1)); + let y = to_f32(args.get(2)); + let size = to_f32(args.get(3)); + let color = match args.get(4) { + Some(ast::Expr::Record(record)) => { + let r = to_u8(record.get(&"r".into())); + let g = to_u8(record.get(&"g".into())); + let b = to_u8(record.get(&"b".into())); + mq::Color::from_rgba(r, g, b, 255) + } + _ => todo!(), + }; + mq::draw_text(&text, x, y, size, color); ast::UNIT_VALUE } @@ -79,3 +105,10 @@ fn to_f32(value: Option<&ast::Expr>) -> f32 { _ => 0.0, } } + +fn to_string(value: Option<&ast::Expr>) -> String { + match value { + Some(ast::Expr::Value(ast::Value::String(s))) => s.clone(), + _ => "".into(), + } +} diff --git a/src/runtime/types.rs b/src/runtime/types.rs index a089026..4c77384 100644 --- a/src/runtime/types.rs +++ b/src/runtime/types.rs @@ -90,7 +90,7 @@ pub struct Menu { pub menu: bool, } -pub const SCALE: i32 = 1; +pub const SCALE: f32 = 2.0; -pub const SCREEN_WIDTH: i32 = 360 * SCALE; -pub const SCREEN_HEIGHT: i32 = 360 * SCALE; +pub const SCREEN_WIDTH: f32 = 360.0 * SCALE; +pub const SCREEN_HEIGHT: f32 = 360.0 * SCALE;