Raylib 2D & Go - Do something when a collision ends - go

new to Raylib and trying to create a Super Mario clone using Go. I am using rl.CheckCollisionRecs to detect collision between the player and a pipe object, which is using the AABB collision method to detect if a player is hitting the X or Y axis first. The problem I am facing is that when the player collides with the Y, the player's Y position is set to match the pipes y position plus its height as expected. However, the player does not fall back to the ground when they leave the collider. How can I code an action when the rectangles are now longer colliding?
When they player leaves the collider, I want them to fall back to the ground.
func drawColliders() {
for _, current_Pipe := range pipes {
rl.DrawRectangle(current_Pipe.posX, current_Pipe.posY, current_Pipe.width, current_Pipe.height, current_Pipe.Color)
if rl.CheckCollisionRecs(playerDest, rl.NewRectangle(float32(current_Pipe.posX), float32(current_Pipe.posY), float32(current_Pipe.width), float32(current_Pipe.height))) {
var xDistance float32
var yDistance float32
var dx float32
var dy float32
if playerDest.X < float32(current_Pipe.posX) {
dx = float32(current_Pipe.posX) - playerDest.Width
isColliding = true
} else if playerDest.X > float32(current_Pipe.posX-current_Pipe.width) {
dx = float32(current_Pipe.posX) + float32(current_Pipe.width)
isColliding = true
}
if playerDest.Y < float32(current_Pipe.posY) {
dy = float32(current_Pipe.posY) - (playerDest.Y + playerDest.Height)
isColliding = true
} else if playerDest.Y > float32(current_Pipe.posY) {
dy = float32(current_Pipe.posY) + (float32(current_Pipe.posY) + float32(current_Pipe.height))
isColliding = true
}
xDistance = dx
yDistance = dy
// fmt.Println(xDistance, yDistance)
var xAxisTimeToCollide float32 = float32(math.Abs(float64(xDistance) / float64(velocityX)))
var yAxisTimeToCollide float32 = float32(math.Abs(float64(yDistance) / float64(velocityY)))
// fmt.Println("X Time: ", xAxisTimeToCollide, " | Y Time: ", yAxisTimeToCollide)
if xAxisTimeToCollide < yAxisTimeToCollide {
// fmt.Println("Collision on the X axis")
if playerDest.X < float32(current_Pipe.posX) {
playerDest.X = float32(current_Pipe.posX) - playerDest.Width
} else if playerDest.X > float32(current_Pipe.posX-current_Pipe.width) {
playerDest.X = float32(current_Pipe.posX) + float32(current_Pipe.width)
}
} else {
// fmt.Println("Collsion on the Y axis")
playerGrounded = true
playerJumping = false
velocityY = 0
playerDest.Y = float32(current_Pipe.posY) - playerDest.Height
}
}
}

Problem solved. CheckCollisionRecs is checking if there is a collision, but does not check when a collision ends.
My solution was that when a collision was detected, I stored the static objects starting coordinate and ending coordinate (startPoint = obj.positionX, endPoint = obj.positionX + obj.width). Then in my update function, I have an if statement that checks if the players current X position is more than or less than the static objects start or end point.

Related

When creating an angle, how do I control the attributes of the automatically created points?

I'm working with a polygon and attempting to create angles with labels but when angles are created, so are the points used to define them. This would be fine but I can't control the labels on the automatically created points (and I don't know what they are called or how to find out).
var points = [
[0, 0],
[0, 5],
[3, 0]
];
for (k = 0; k < showAngle.length; k++) {
if (showAngle[k] == 1) {
var angle = board.create('angle', [points[k], points[((k + 1) % points.length)], points[((k + 2) % points.length)]],{fixed:true});
} else if (showAngle[k] == 2) {
var angle = board.create('angle', [points[k], points[((k + 1) % points.length)], points[((k + 2) % points.length)]], {
fixed: false,
name: function() {
return ((180/Math.PI)*JXG.Math.Geometry.rad(points[k], points[((k + 1) % points.length)], points[((k + 2) % points.length)])).toFixed(1) + '°';
}
});
}
}
https://jsfiddle.net/jscottuq/acyrLxfh/12/ contains what I've got so far.
The arrays showLen and showAngle are setting what labels are shown for each side/angle (0 - no label, 1 - name , 2 - measurement).
These will be set when the jsxgraph is created.
At the time being, the possibility to control the style of the newly created points of an angle is missing. We will add this soon.
However, a solution would be to use the already existing points which are hidden in this example. For this it would be helpful to kee a list of these points, e.g. jxg_points:
var jxg_points = [];
for (i = 0; i < points.length; i++) {
var rise = points[(i + 1) % points.length][1] - points[i][1];
var run = points[(i + 1) % points.length][0] - points[i][0];
var point = board.create('point', [points[i][0], points[i][1]], {
fixed: true,
visible:false
});
jxg_points.push(point); // Store the point
points[i].pop();
len[i] = Math.round((Math.sqrt(rise * rise + run * run) + Number.EPSILON) * 100) / 100;
}
Then the points can be reused for the angles without creating new points:
for (k = 0; k < showAngle.length; k++) {
if (showAngle[k] == 1) {
angle = board.create('angle', [
jxg_points[k],
jxg_points[((k + 1) % jxg_points.length)],
jxg_points[((k + 2) % jxg_points.length)]
],{fixed:true});
} else if (showAngle[k] == 2) {
var angle = board.create('angle', [
jxg_points[k],
jxg_points[((k + 1) % jxg_points.length)],
jxg_points[((k + 2) % jxg_points.length)]], {
fixed: false,
name: function() {
return ((180/Math.PI)*JXG.Math.Geometry.rad(points[k], points[((k + 1) % points.length)], points[((k + 2) % points.length)])).toFixed(1) + '°';
}
});
}
}
See it live at https://jsfiddle.net/d8an0epy/.

How to implement snapping effect and collision detection between two objects using Threejs?

We are able to detect the collision but could not implement a snapping/magnetic effect like Snap edges of objects to each other and prevent overlap
we need help with 3D objects here and we are using Vec3 for the active object's position.
With the following approach, collision detection is working perfectly for all cases, and magnetic effect is somehow working - not perfectly.
It's working well when the object is moving along x or z-axis but when the object's movement is in diagonal direction (moving along x and z-axis simultaneously) that is where the problem comes.
Though am not satisfied with the following approach that's why am looking for new approach to implement both magnetic and collision detection features.
It is not necessary to have the solution in Threejs, any general solution or algorithm of coordinates can be converted into Threejs.
let collide = this.detectCollisionCubes(activeObject, collidingObject, vec3);
let magneticEffect = new MagneticEffect(activeObject, vec3, collidingObject);
vec3 = magneticEffect.setNewPosition();
activeObject.position.copy(vec3);
detectCollisionCubes = function(a, d, vec3){
// a is active object's positon
// d is colliding object
let aHeight = Math.abs(a.getHeight());
let aWidth = Math.abs(a.getWidth());
let aDepth = Math.abs(a.getDepth());
let b1 = vec3.y - aHeight / 2;
let t1 = vec3.y + aHeight / 2;
let r1 = vec3.x + aWidth / 2;
let l1 = vec3.x - aWidth / 2;
let f1 = vec3.z - aDepth / 2;
let B1 = vec3.z + aDepth / 2;
let dHeight = Math.abs(d.getHeight());
let dWidth = Math.abs(d.getWidth());
let dDepth = Math.abs(d.getDepth());
let b2 = d.position.y - dHeight / 2;
let t2 = d.position.y + dHeight / 2;
let r2 = d.position.x + dWidth / 2;
let l2 = d.position.x - dWidth / 2;
let f2 = d.position.z - dDepth / 2;
let B2 = d.position.z + dDepth / 2;
if (t1 < b2 || r1 < l2 || b1 > t2 || l1 > r2 || f1 > B2 || B1 < f2) {
return false;
}
return true;
}
Trying to create magnetic effect via
this.currentObject = currentObject;
this.collisionObject = collisionObject;
this.collisionType = null;
this.objectType = null;
this.currentPosition = currentPosition;
this.currentObjectHeight = Math.abs(currentObject.getHeight());
this.currentObjectWidth = Math.abs(currentObject.getWidth());
this.collisionObjectHeight = Math.abs(collisionObject.getHeight());
this.collisionObjectWidth = Math.abs(collisionObject.getWidth());
this.collisionObjectDepth = Math.abs(collisionObject.getDepth());
this.objectTop = currentObject.position.y + (this.currentObjectHeight/2);
this.objectBottom = currentObject.position.y - (this.currentObjectHeight/2);
this.collideTop = collisionObject.position.y + (this.collisionObjectHeight/2);
this.collideBottom = collisionObject.position.y - (this.collisionObjectHeight/2);
this.zAxisDifference = Math.abs(Math.abs(currentPosition.z) - Math.abs(collisionObject.position.z));
this.xAxisDifference = Math.abs(Math.abs(currentPosition.x) - Math.abs(collisionObject.position.x));
// Extra code here
if (
this.objectTop < this.collideBottom
) {
this.collisionType = collisionTypes.verticalBottom;
} else if (
this.objectBottom > this.collideTop
) {
this.collisionType = collisionTypes.verticalTop;
} else if (
this.currentPosition.x > this.collisionObject.position.x &&
this.zAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalXLeft;
} else if (
this.currentPosition.x < this.collisionObject.position.x &&
this.zAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalXRight;
} else if (
this.currentPosition.z > this.collisionObject.position.z &&
this.xAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalZLeft;
} else if (
this.currentPosition.z < this.collisionObject.position.z &&
this.xAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalZRight;
}
MagneticEffect.prototype.setNewPosition = function () {
if (this.collisionType === collisionTypes.verticalBottom) {
this.currentPosition.y = this.collideBottom + 0.5;
} else if (this.collisionType === collisionTypes.verticalTop) {
this.currentPosition.y = this.collideTop - 0.5;
} else if (this.collisionType === collisionTypes.horizentalXRight) {
this.currentPosition.x = this.collisionObject.position.x - this.collisionObjectWidth - 0.5;
} else if (this.collisionType === collisionTypes.horizentalXLeft) {
this.currentPosition.x = this.collisionObject.position.x + this.collisionObjectWidth + 0.5;
} else if (this.collisionType === collisionTypes.horizentalZRight) {
this.currentPosition.z = this.collisionObject.position.z - this.collisionObjectWidth - 0.5;
} else if (this.collisionType === collisionTypes.horizentalZLeft) {
this.currentPosition.z = this.collisionObject.position.z + this.collisionObjectWidth + 0.5;
}
return this.currentPosition;
};

Algorithm to shift a point relative to the position of two other points,

So I have two sets of paths, which I am using to draw lines.
The second line is movable by the users(black line). They can pick an end and move it in a circle around the other end as a fulcrum. What I want to do is make the second line move relative to its position to the beginning and end points of the black line.
I thought I could use the angles of a triangle that each path point makes with the beginning and ending points of the movable black line, but I can't seem to get it working. Right now if I move one end even a little it takes the line and add all these loops.
Here is my code:
fun transmuteOutlineWithRatio(angle: Double, newPoint: PointF){
val tempTries = mutableListOf<Triangle>()
outlineTriangles.forEach { triangle ->
//add the angle by which the black line has been moved to the angle of the pathpoint to the fixed point on the movable path.
val newAngle = angle + (triangle.aAngle?: 0.0)
val r = getLength(triangle.C, triangle.A)
val cosX = Math.cos(newAngle)
val sinY = Math.sin(newAngle)
val newX = r * cosX
val newY = r * sinY
val newTri = triangle.copy(B = newPoint, C = PointF(triangle.C.x+ newX.toFloat(), triangle.C.y + newY.toFloat()))
tempTries.add(newTri)
}
outlineTriangles.clear()
outlineTriangles.addAll(tempTries)
}
fun getLength(pointA: PointF, pointB: PointF): Double {
val xsum = (pointA.x - pointB.x)
val ysum = (pointA.y - pointB.y)
val sumOfSquares = (xsum * xsum) + (ysum * ysum)
return Math.sqrt(sumOfSquares.toDouble())
}
and the triangle code:
package com.example.testcanvas
import android.graphics.PointF
data class Triangle(var A: PointF,
var B: PointF,
var C: PointF,
var aAngle: Double? = null,
var bAngle: Double? = null,
var cAngle: Double? = null) {
init {
setAngle(A, B, C)
}
fun setAngle(pointA: PointF, pointB: PointF, pointC: PointF) {
val sideA = lengthSquar(pointB, pointC)
val sideB = lengthSquar(pointA, pointC)
val sideC = lengthSquar(pointA, pointB)
val a = Math.sqrt(sideA.toDouble())
val b = Math.sqrt(sideB.toDouble())
val c = Math.sqrt(sideC.toDouble())
var alpha = Math.acos((sideB + sideC - sideA) / (2 * b * c))
var betta = Math.acos((sideA + sideC - sideB) / (2 * a * c))
var gamma = Math.acos((sideA + sideB - sideC) / (2 * a * b))
//convert to degrees
aAngle = alpha * 180 / Math.PI
bAngle = betta * 180 / Math.PI
cAngle = gamma * 180 / Math.PI
}
fun lengthSquar(pointA: PointF, pointB: PointF): Float {
val xDiff = (pointA.x - pointB.x)
val yDiff = (pointA.y - pointB.y)
return (xDiff * xDiff) + (yDiff * yDiff)
}
}

xcode stop a sprite from going off screen cocos2d

im using the below code but that doesnt seem to be stopping the sprite from going off screen even though the code builds. can anyone tell me how it needs to be changed so that when the sprite gets to the edge of the screen along the x coordinate it stops.
-(void)applyJoystick:(SneakyJoystick *)aJoystick toNode:(CCNode *)tempNode forTimeDelta:(float)deltaTime
{
CGPoint scaledVelocity = ccpMult(aJoystick.velocity, 1024.0f);
CGPoint newPosition = ccp(tempNode.position.x + scaledVelocity.x * deltaTime, tempNode.position.y);
CGSize screenSize = [CCDirector sharedDirector].winSize;
CGFloat spriteWidth = vikingSprite.contentSize.width;
CGFloat x = tempNode.position.x + scaledVelocity.x * deltaTime;
if (x < 0 + (spriteWidth/2)) {
x = 0 + (spriteWidth/2);
} else if (x > screenSize.width - (spriteWidth/2)) {
x = screenSize.width - (spriteWidth/2);
}
[tempNode setPosition:newPosition];
if (jumpButton.active == YES) {
CCLOG(#"Jump button is pressed.");
}
if (attackButton.active == YES) {
CCLOG(#"Attack button is pressed.");
}
}
thanks
You never re-assign the changed variable x back to your vikingsprite after you modified it.
So you need to do something like:
if (x < 0 + (spriteWidth/2)) {
x = 0 + (spriteWidth/2);
} else if (x > screenSize.width - (spriteWidth/2)) {
x = screenSize.width - (spriteWidth/2);
}
CGPoint vikingPos = cpp(x, vikingsprite.position.y);
[vikingsprite setPosition:vikingPos];
My syntax could be wrong I don't write a lot of objective-c, but I use cocos2d-x which is the C++ version of cocos2d
Set edge as boundary.
boundary.SetAsEdge(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0));
Don't forget to send Ray Wenderlich a beer.
I think your forgetting to reset it's position?
if (x < 0 + (spriteWidth/2)) {
x = 0 + (spriteWidth/2);
tempNode.position.x = x;
} else if (x > screenSize.width - (spriteWidth/2)) {
x = screenSize.width - (spriteWidth/2);
tempNode.position.x = x;
}

Calculate daylight hours Based on gegraphical coordinates

I want to calculate Daylight hours based on given Latitude and Longitude and DateTime
I mean calculate the time of sunrise and the time of sunset in a specefic Date and based on gegraphic coordinate.
Check this Latitude and Longitude and Daylight Hours
D = daylength
L = latitude
J = day of the year
P = asin[.39795*cos(.2163108 + 2*atan{.9671396*tan[.00860(J-186)]})]
_ _
/ sin(0.8333*pi/180) + sin(L*pi/180)*sin(P) \
D = 24 - (24/pi)*acos{ ----------------------------------------- }
\_ cos(L*pi/180)*cos(P) _/
Here is a python function that returns the number of hours of daylight with arguments of latitude and day of the year(number between 1-356):
import math
def Daylight(latitude,day):
P = math.asin(0.39795 * math.cos(0.2163108 + 2 * math.atan(0.9671396 * math.tan(.00860 * (day - 186)))))
pi = math.pi
daylightamount = 24 - (24 / pi) * math.acos(
(math.sin((0.8333 * pi / 180) + math.sin(latitude * pi / 180) * math.sin(P)) / (math.cos(latitude * pi / 180) * math.cos(P))))
return daylightamount
I just answered another question, and think that my solution is fitting here aswell. It's a Javascript solution, so you should be able to convert easily to other languages if you need.
I've created a repository under GitHub Sundial it is licenced under the permissive modified BSD license, so you can use it freely in your own projects.
It should be accurate to 0.0001 minutes and takes into account the axial tilt of the earth, and the equation of time.
Sundial AMD Loadable Sun Day Light Calculator
/* Credit and References */
// http://lexikon.astronomie.info/zeitgleichung/ EOT
// http://articles.adsabs.harvard.edu/cgi-bin/nph-iarticle_query?bibcode=1989MNRAS.238.1529H&db_key=AST&page_ind=2&plate_select=NO&data_type=GIF&type=SCREEN_GIF&classic=YES
// http://code.google.com/p/eesim/source/browse/trunk/EnergySim/src/sim/_environment.py?spec=svn6&r=6
// http://mathforum.org/library/drmath/view/56478.html
// http://www.jgiesen.de/elevaz/basics/meeus.htm
// http://www.ehow.com/how_8495097_calculate-sunrise-latitude.html
// http://www.jgiesen.de/javascript/Beispiele/TN_Applet/DayNight125d.java
// http://astro.unl.edu/classaction/animations/coordsmotion/daylighthoursexplorer.html
// http://www.neoprogrammics.com/nutations/Nutation_In_Longitude_And_RA.php
(function (factory) {
if (typeof define === 'function' && define.amd ) {
// AMD. Register as module
if(typeof dojo === 'object') {
define(["dojo/_base/declare"], function(declare){
return declare( "my.calc.Sun", null, factory());
});
} else {
define( 'Sundial', null, factory());
}
} else {
Sun = new factory();
}
}(function () {
return {
date : new Date(),
getDate : function(){
return this.date;
},
setDate : function(d){
this.date = d;
return this;
},
getJulianDays: function(){
this._julianDays = Math.floor(( this.date / 86400000) - ( this.date.getTimezoneOffset() / 1440) + 2440587.5);
return this._julianDays;
},
// Calculate the Equation of Time
// The equation of time is the difference between apparent solar time and mean solar time.
// At any given instant, this difference will be the same for every observer on Earth.
getEquationOfTime : function (){
var K = Math.PI/180.0;
var T = (this.getJulianDays() - 2451545.0) / 36525.0;
var eps = this._getObliquity(T); // Calculate the Obliquity (axial tilt of earth)
var RA = this._getRightAscension(T);
var LS = this._getSunsMeanLongitude(T);
var deltaPsi = this._getDeltaPSI(T);
var E = LS - 0.0057183 - RA + deltaPsi*Math.cos(K*eps);
if (E>5) {
E = E - 360.0;
}
E = E*4; // deg. to min
E = Math.round(1000*E)/1000;
return E;
},
getTotalDaylightHoursInYear : function(lat){
// We can just use the current Date Object, and incrementally
// Add 1 Day 365 times...
var totalDaylightHours = 0 ;
for (var d = new Date(this.date.getFullYear(), 0, 1); d <= new Date(this.date.getFullYear(), 11, 30); d.setDate(d.getDate() + 1)) {
this.date = d;
// console.log( this.getDaylightHours(lat) );
totalDaylightHours += this.getDaylightHours(lat);
}
return totalDaylightHours;
},
getDaylightHours : function (lat) {
var K = Math.PI/180.0;
var C, Nenner, C2, dlh;
var T = (this.getJulianDays() - 2451545.0) / 36525.0;
this._getRightAscension(T); // Need to get the Suns Declination
Nenner = Math.cos(K*lat)*Math.cos(K*this._sunDeclination);
C = -Math.sin(K*this._sunDeclination)*Math.sin(K*lat)/Nenner;
C2=C*C;
// console.log( T, C2, C, Nenner, lat, K, Math.cos(K*lat) );
if ((C>-1) && (C<1)) {
dlh=90.0 - Math.atan(C / Math.sqrt(1 - C2)) / K;
dlh=2.0*dlh/15.0;
dlh=Math.round(dlh*100)/100;
}
if (C>1) {
dlh=0.0;
}
if (C<-1) {
dlh=24.0;
}
return dlh;
},
_getRightAscension : function(T) {
var K = Math.PI/180.0;
var L, M, C, lambda, RA, eps, delta, theta;
L = this._getSunsMeanLongitude(T); // Calculate the mean longitude of the Sun
M = 357.52910 + 35999.05030*T - 0.0001559*T*T - 0.00000048*T*T*T; // Mean anomoly of the Sun
M = M % 360;
if (M<0) {
M = M + 360;
}
C = (1.914600 - 0.004817*T - 0.000014*T*T)*Math.sin(K*M);
C = C + (0.019993 - 0.000101*T)*Math.sin(K*2*M);
C = C + 0.000290*Math.sin(K*3*M);
theta = L + C; // get true longitude of the Sun
eps = this._getObliquity(T);
eps = eps + 0.00256*Math.cos(K*(125.04 - 1934.136*T));
lambda = theta - 0.00569 - 0.00478*Math.sin(K*(125.04 - 1934.136*T)); // get apparent longitude of the Sun
RA = Math.atan2(Math.cos(K*eps)*Math.sin(K*lambda), Math.cos(K*lambda));
RA = RA/K;
if (RA<0) {
RA = RA + 360.0;
}
delta = Math.asin(Math.sin(K*eps)*Math.sin(K*lambda));
delta = delta/K;
this._sunDeclination = delta;
return RA;
},
// Calculate the Mean Longitude of the Sun
_getSunsMeanLongitude : function(T){
var L = 280.46645 + 36000.76983*T + 0.0003032*T*T;
L = L % 360;
if (L<0) {
L = L + 360;
}
return L;
},
// Nutation in ecliptical longitude expressed in degrees.
_getDeltaPSI : function(T){
var K = Math.PI/180.0;
var deltaPsi, omega, LS, LM;
LS = this._getSunsMeanLongitude(T);
LM = 218.3165 + 481267.8813*T;
LM = LM % 360;
if (LM<0) {
LM = LM + 360;
}
// Longitude of ascending node of lunar orbit on the ecliptic as measured from the mean equinox of date.
omega = 125.04452 - 1934.136261*T + 0.0020708*T*T + T*T*T/450000;
deltaPsi = -17.2*Math.sin(K*omega) - 1.32*Math.sin(K*2*LS) - 0.23*Math.sin(K*2*LM) + 0.21*Math.sin(K*2*omega);
deltaPsi = deltaPsi/3600.0;
return deltaPsi;
},
// T = Time Factor Time factor in Julian centuries reckoned from J2000.0, corresponding to JD
// Calculate Earths Obliquity Nutation
_getObliquity : function (T) {
var K = Math.PI/180.0;
var LS = this._getSunsMeanLongitude(T);
var LM = 218.3165 + 481267.8813*T;
var eps0 = 23.0 + 26.0/60.0 + 21.448/3600.0 - (46.8150*T + 0.00059*T*T - 0.001813*T*T*T)/3600;
var omega = 125.04452 - 1934.136261*T + 0.0020708*T*T + T*T*T/450000;
var deltaEps = (9.20*Math.cos(K*omega) + 0.57*Math.cos(K*2*LS) + 0.10*Math.cos(K*2*LM) - 0.09*Math.cos(K*2*omega))/3600;
return eps0 + deltaEps;
}
};
}));
Demo jsFiddle
You can check out a demo of how you might use it on jsfiddle.
http://jsfiddle.net/wjKRw/
And then when I get around to it, check out the sample use cases at the repository.
GitHub Sundial
sin24+(24cos-18^12)^(day number of the year)+(latitude)^24= #of daylight hours

Resources