Skip to content

Commit

Permalink
Add New Features
Browse files Browse the repository at this point in the history
  • Loading branch information
isHarryh committed Dec 22, 2022
1 parent f9b8417 commit a4267c6
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 18 deletions.
48 changes: 33 additions & 15 deletions core/src/com/isharryh/arkpets/ArkPets.java
Original file line number Diff line number Diff line change
Expand Up @@ -271,27 +271,45 @@ private HWND refreshWindowIdx() {
int myPos = (int)(WD_poscur.x + WD_W / 2);
int minNum = 2048;
int myNum = getArkPetsWindowNum(APP_TITLE);
final float quantityProduct = 1;
if (plane != null) {
// Reset plane additions.
plane.barriers.clear();
plane.pointCharges.clear();
}
for (HWndCtrl hWndCtrl : windowList) {
// Find windows as ground
if ((getArkPetsWindowNum(hWndCtrl.windowText) == -1) && hWndCtrl.posLeft <= myPos && myPos <= hWndCtrl.posRight) {
// This window IS in the vertical line that the app lies.
if (hWndCtrl.posBottom > 0 && hWndCtrl.posTop < SCR_H) {
for (int h = Math.max(hWndCtrl.posTop, 0); h < (Math.min(hWndCtrl.posBottom, SCR_H)); h++) {
if (line[h] == null)
line[h] = (h == hWndCtrl.posTop) ? hWndCtrl : new HWndCtrl();
int wndNum = getArkPetsWindowNum(hWndCtrl.windowText);
// Distinguish non-peer windows from peers.
if (wndNum == -1){
if (hWndCtrl.posLeft <= myPos && myPos <= hWndCtrl.posRight) {
// This window "is" in the vertical line that the app lies.
if (hWndCtrl.posBottom > 0 && hWndCtrl.posTop < SCR_H) {
// This window is "under" the app.
for (int h = Math.max(hWndCtrl.posTop, 0); h < (Math.min(hWndCtrl.posBottom, SCR_H)); h++) {
if (line[h] == null)
line[h] = (h == hWndCtrl.posTop) ? hWndCtrl : new HWndCtrl(); // Record this window.
}
}
}
} else {
if (plane != null && wndNum != myNum) {
// Set point charges.
plane.setPointCharge(-hWndCtrl.getCenterY(), hWndCtrl.getCenterX(), quantityProduct);
}
// Find the last peer window.
if (wndNum > myNum && wndNum < minNum) {
minNum = getArkPetsWindowNum(hWndCtrl.windowText);
minWindow = hWndCtrl.hWnd;
}
}
// Find the last peer window.
if (getArkPetsWindowNum(hWndCtrl.windowText) > myNum && getArkPetsWindowNum(hWndCtrl.windowText) < minNum) {
minNum = getArkPetsWindowNum(hWndCtrl.windowText);
minWindow = hWndCtrl.hWnd;
}
// Window iteration end.
}
if (minWindow == null) {
// Set as the top window if there is no peer.
minWindow = new HWND(Pointer.createConstant(-1));
}
minWindow = (minWindow == null) ? new HWND(Pointer.createConstant(-1)) : minWindow; // Set as the top window if there is no peer.
if (plane != null) {
// Reset barriers
plane.barriers.clear();
// Set barriers.
for (int h = WD_H; h < SCR_H; h++) {
HWndCtrl temp = line[h];
if (temp != null && temp.hWnd != null) {
Expand Down
14 changes: 14 additions & 0 deletions core/src/com/isharryh/arkpets/utils/HWndCtrl.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ public boolean isVisible() {
return true;
}

/** Get the center X position.
* @return X.
*/
public float getCenterX() {
return posLeft + windowWidth / 2f;
}

/** Get the center Y position.
* @return Y.
*/
public float getCenterY() {
return posTop + windowHeight / 2f;
}

/** Get the current list of windows.
* @param $only_visible Only the visible window allowed.
* @return An ArrayList consists of HWndCtrls.
Expand Down
48 changes: 45 additions & 3 deletions core/src/com/isharryh/arkpets/utils/Plane.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public class Plane {
private float airFrict;
private float staticFrict;
private boolean dropped = false;
private float droppedHeight = 0;
static float droppedThreshold = 10f;

/** Initialize a plane with gravity field.
* The origin of coordinates (0,0) is the left-bottom point.
Expand All @@ -35,6 +37,7 @@ public Plane(int $worldWidth, int $worldHeight, float $gravity) {
speed = new Vector2(0, 0);
speedLimit = new Vector2(0, 0);
barriers = new ArrayList<>();
pointCharges = new ArrayList<>();
world = new Vector2($worldWidth, $worldHeight);
obj = new Vector2(0, 0);
bounce = 0;
Expand Down Expand Up @@ -96,12 +99,13 @@ public void updatePosition(float $deltaTime) {
float deltaX = speed.x * $deltaTime;
float deltaY = speed.y * $deltaTime;
final float borderBottom = borderBottom();
droppedHeight = Math.max(Math.signum(gravity) * (position.y - borderBottom), droppedHeight);
if (position.y != borderBottom && limitY(deltaY + position.y) == borderBottom) {
// When it fell to the ground.
if (Math.signum(gravity) * (position.y - borderBottom) > 0)
dropped = true;
speed.y = 0;
}
// System.out.println("Y:delta"+deltaY+",speed"+speed.y+",bottom"+borderBottom()+",want"+(deltaY+position.y)+",limit"+limitY(deltaY + position.y));
position.set(limitX(deltaX + position.x), limitY(deltaY + position.y));
}

Expand All @@ -118,6 +122,16 @@ public void setBarrier(float $posTop, float $posLeft, float $width, boolean $ove
barriers.add(new Vector3($posLeft, $posTop, $width));
}

/** Set a point charge whose excited electric field can repulse the object.
* The position and quantity of the charge are fixed.
* @param $posTop The y-position of the charge (px).
* @param $posLeft The x-position of the charge (px).
* @param $quantityProduct The product of the point's quantity and the object's quantity (C^2).
*/
public void setPointCharge(float $posTop, float $posLeft, float $quantityProduct) {
pointCharges.add(new Vector3($posLeft, $posTop, $quantityProduct));
}

/** Get the x-position of the object.
* @return X (px).
*/
Expand All @@ -138,7 +152,10 @@ public float getY() {
public boolean getDropped() {
if (dropped) {
dropped = false; // Reset
return true;
if (droppedHeight >= droppedThreshold) {
droppedHeight = 0; // Reset
return true;
}
}
return false;
}
Expand All @@ -163,6 +180,14 @@ private void updateVelocity(float $deltaTime) {
}
else if (position.y == TOP && speed.y > 0)
speed.y = 0;
// Electrostatic forces
for (Vector3 pc : pointCharges) {
float dx = position.x + obj.x / 2f - pc.x;
float dy = position.y + obj.y / 2f - pc.y;
float hypot = (float)Math.hypot(dx, dy);
speed.x = applyElectrostaticEffect(speed.x, pc.z, hypot, dx / hypot, $deltaTime);
speed.y = applyElectrostaticEffect(speed.y, pc.z, hypot, dy / hypot , $deltaTime);
}
// Ground friction
if (position.y == BOTTOM)
speed.x = applyFriction(speed.x, staticFrict, $deltaTime);
Expand All @@ -181,7 +206,7 @@ else if (position.y == TOP && speed.y > 0)
}

/** Apply a friction to a velocity.
* @param $speed The velocity (px/s).
* @param $speed The original velocity (px/s).
* @param $frict The acceleration of friction (px/s^2).
* @param $deltaTime Delta time (s).
* @return New velocity (px/s).
Expand All @@ -191,6 +216,23 @@ private float applyFriction(float $speed, float $frict, float $deltaTime) {
return Math.signum($speed - delta) == Math.signum(delta) ? $speed - delta : 0;
}

/** Apply the electrostatic effect of a point charge to a velocity.
* @param $speed The original velocity (px/s).
* @param $quantityProduct The product of the point's quantity and the object's quantity (C^2).
* @param $distance The absolute distance between the point charge and the object.
* @param $cosine The cosine of the included angel between the distance and its projection on the direction of speed.
* @param $deltaTime Delta time (s).
* @return New velocity (px/s).
*/
private float applyElectrostaticEffect(float $speed, float $quantityProduct, float $distance, float $cosine, float $deltaTime){
final float k = 2500 * (float)Math.hypot(obj.x, obj.y); // Electrostatic force constant
final float dm = 10; // Min distance
$distance = Math.max(Math.abs($distance), dm); // Limit the distance
float delta = k * $quantityProduct / $distance / $distance * $cosine * $deltaTime;
//System.out.println("speed+="+delta);
return $speed + delta;
}

/** Limit the x-position to avoid overstepping.
* @param $x X (px).
* @return New x (px).
Expand Down

0 comments on commit a4267c6

Please sign in to comment.