2 次代碼提交 cbc2814e85 ... 3dd1f7f235

作者 SHA1 備註 提交日期
  namark 3dd1f7f235 boxing: two eyes that can look about and pop out! 2 月之前
  namark 63e1a73e80 array iterator is not raw pointer in libcpp, 2 月之前
共有 2 個文件被更改,包括 68 次插入20 次删除
  1. 66 18
      boxing.cpp
  2. 2 2
      bunny.cpp

+ 66 - 18
boxing.cpp

@@ -8,7 +8,9 @@
 // TODO: menu - 1/2 players, audio levels
 // TODO: menu - gore level (in case become olympic sport),
 //
-// TODO: menu - hoboplayer
+// TODO: menu - hoboplayer, with broadcast discovery
+//
+// from game fade away to main menu if no input, form main menu fade away to program.end() if no input
 
 /*
 #canvas {
@@ -163,8 +165,12 @@ struct complayer
 
 struct eye_t
 {
-	float2 position;
-	float2 velocity;
+	constexpr static auto size = float2::one(0.035f);
+
+	float2 position = {};
+	float2 velocity = {};
+	float2 drift = {};
+	unsigned pop_damage = 100;
 };
 
 struct boxa
@@ -181,7 +187,8 @@ struct boxa
 	std::optional<keymap> controls{};
 	std::optional<complayer> brainz;
 
-	eye_t eye = {position};
+	std::array<eye_t,2> eyes = {{ {position + float2::j() * eye_t::size * 1.2f}, {position - float2::j() * eye_t::size * 1.2f} }};
+	melody<movement<float, quadratic_out>, movement<float, motion::quadratic_curve>> eye_drift = { {1s, 0, 1}, {1s, 1, 0}};
 
 	float punch = 0.0f;
 	bool hit = false;
@@ -256,7 +263,7 @@ struct boxa
 	void draw(frame& f, auto delta_time)
 	{
 		const auto direction = this->direction();
-		const auto normal = common::rotate(this->direction(), common::protractor<>::tau(1/4.f));
+		const auto normal = common::rotate(direction, common::protractor<>::tau(1/4.f));
 		const auto facingdom = float2x2{direction, normal};
 		auto body = this->body();
 		{
@@ -331,17 +338,59 @@ struct boxa
 			glove_sketch.fill(cola);
 		}
 
+
+		{ // move eyes, techincally physics but purely visual and need the visually augmented body geometry
+			auto drift_ratio = 0.f;
+			if(motion::loop(drift_ratio, eye_drift, delta_time))
+				for(auto&& eye : eyes)
+					eye.drift = (trand_float2() - 0.5f);
+
+			auto eye_difference = eyes[0].position - eyes[1].position;
+			const auto overlapance = eye_t::size.x() * eye_t::size.x() - eye_difference.quadrance();
+			if(overlapance > 0)
+			{
+				auto impact_surface = common::rotate(eye_difference, common::protractor<>::tau(1/4.f));
+				float side = 1;
+				for(auto&& eye : eyes)
+				{
+					eye.drift = common::reflect(eye.drift, impact_surface);
+					eye.position += side * common::normalize(eye_difference) * support::root2(overlapance)/2;
+					side = -side;
+				}
+			}
+
+			float side = 1;
+			for(auto&& eye : eyes)
+			{
+				const auto socket_position = body.position + eye_t::size/2 * (direction + side * normal * 1.2f); // +20% seperation
+				auto eye_offset = socket_position - eye.position;
+				eye.velocity = 10 * eye_offset;
+				eye.position += (eye.velocity + drift_ratio * eye.drift) * delta_time.count();
+				side = -side;
+				if(damage < eye.pop_damage)
+					eye.position = socket_position;
+			}
+		}
+
+		const auto look_direction = common::normalize(target->position - position);
+		for(auto&& eye : eyes)
 		{
-			const auto eye_direction = eye.velocity != float2::zero() ? -common::normalize(eye.velocity) : this->direction();
+			bool eye_popped = damage >= eye.pop_damage;
+			const auto eye_direction = (eye.velocity != float2::zero() && eye_popped) ? -common::normalize(eye.velocity) : look_direction;
 			const auto eye_normal = common::rotate(eye_direction, common::protractor<>::tau(1/4.f));
-			const auto eye_facingdom = float2x2{eye_direction * (1+eye.velocity.quadrance()), eye_normal};
-			auto scaled_eye = scale(rect{float2::one(0.04f), eye.position}, ring);
+			const auto eye_stretch = eye_popped ? 1+eye.velocity.quadrance() : 1;
+			const auto eye_facingdom = float2x2{eye_direction * eye_stretch, eye_normal};
+			auto scaled_eye = scale(rect{eye_t::size, eye.position}, ring);
+			auto scaled_pupil = scale(rect{eye_t::size/2, eye.position + eye_direction * eye_t::size * 0.45f}, ring);
+			f.begin_sketch()
+				.ellipse(scaled_pupil.position, eye_facingdom * geom::column(scaled_pupil.size/2))
+				.fill(rgb::white(0.f)) // hmm...
+			;
 			f.begin_sketch()
 				.ellipse(scaled_eye.position, eye_facingdom * geom::column(scaled_eye.size/2))
 				.fill(rgb::white())
 			;
 		}
-
 	}
 
 	void move(auto delta_time)
@@ -397,17 +446,10 @@ struct boxa
 				}
 			}
 		}
-
-		{
-			auto eye_offset = position - eye.position;
-				eye.velocity = 10 * eye_offset;
-			eye.position += eye.velocity * delta_time.count();
-		}
 	}
 
 	void update(frame& f, auto delta_time)
 	{
-
 		move(delta_time);
 		draw(f, delta_time);
 	}
@@ -476,8 +518,14 @@ void start(Program& program)
 	boxas[1].brainz = complayer{};
 	// boxas[0].brainz = complayer{};
 
-	boxas[0].idle.advance(trand_float() * boxas[0].idle.total);
-	boxas[1].idle.advance(trand_float() * boxas[0].idle.total);
+	for(auto&& boxa : boxas)
+	{
+		boxa.idle.advance(trand_float() * boxa.idle.total);
+		auto last_pop = trand_int({70,91});
+		auto last_eye = trand_int({0,2});
+		boxa.eyes[last_eye].pop_damage = last_pop;
+		boxa.eyes[not last_eye].pop_damage = last_pop - trand_int({10,21});
+	}
 
 	if(program.argc > 2)
 	{

+ 2 - 2
bunny.cpp

@@ -78,7 +78,7 @@ struct circle
 	}
 };
 
-bool contain(range<circle*> circles, float2 point)
+bool contain(auto circles, float2 point)
 {
 	for(auto [center, radius] : circles)
 		if(quadrance(center - point) < radius*radius)
@@ -126,7 +126,7 @@ polygon make_nose(float2 aspect)
 	return nose;
 };
 
-void some_fur(frame& frame, rgb_pixel color, range<circle*> eyes, const polygon& nose)
+void some_fur(frame& frame, rgb_pixel color, auto eyes, const polygon& nose)
 {
 	const auto aspect = frame.size/frame.size.x();
 	const auto fur_length = support::average(frame.size.x(),frame.size.y())*12/400;