Game Maker Studio - Preventing objects from sliding vertically - collision

When my object jumps over a block, if it cannot, it sticks with the side of the wall for a few seconds before the object drops slightly and sticks again until it hits the floor. During this time, the user can jump again allowing them to bypass any wall.
Any ideas on how to fix this?
if (place_meeting(x+hsp,y,Room))
{
while (!place_meeting(x+sign(hsp),y,Room))
{
x += sign(hsp);
}
hsp = 0;
}
x += hsp;
//VerticalCollision
if (place_meeting(x,y+vsp,Room))
{
while (!place_meeting(x,y+sign(vsp),Room))
{
y += sign(vsp);
}
vsp = 0;
The above code handles collisions in the game, with experimenting I've messed it up even more now. The character will stand against a wall and everything will freeze...
I'm using a collision mask but that hasn't helped.

Would be easier if we could see your jumping/movement code.
Generally, Freezing is caused by infinite while loops, try adding a limiter.
if (place_meeting(x+hsp,y,Room))
{
var a = 64;
while (!place_meeting(x+sign(hsp),y,Room) and 64 > 0 )
{
a --;
x += sign(hsp);
}
hsp = 0;
}
Also, why are you colliding with Room? Whats Room?

Related

Creating a for loop in MQL4 that counts the bars

So I am trying to make a for loop which counts 4 bars. Every bearish bar is negative and every bullish bar is positive. So the sum of all 4 bars should give me a number that is greater, less, or equal to 0. This I need to see the current price movement. This information is needed to enter a trade. What I want is after a trade is closed, that the for loop starts counting from this bar onwards. Because the problem I run into is that the program starts counting 5 bars after the trade closed giving false signals. How can I make the program count forward from the new bar?
for(int i = 5; i>0; i--){
if(Open[i]>Close[i]){
z = z - 1;
}
else if(Open[i]<Close[i]){
z = z + 1;
}
else{
z = z;
}
}
If you want to count back 5 bars from and including the current bar, then you would use the following code (note, there is no need for the z=z statement, it achieves nothing). You would have to make a function that returns the bar number for the last closed trade.
if(lastTradeClosed()==0)
{
for(int i=0; i<=4; i++)
{
if(Open[i]>Close[i]) z--;
else if(Open[i]<Close[i]) z++;
}
}

Find largest circle not overlapping with others using genetic algorithm

I'm using GA, so I took example from this page (http://www.ai-junkie.com/ga/intro/gat3.html) and tried to do on my own.
The problem is, it doesn't work. For example, maximum fitness does not always grow in the next generation, but becomes smallest. Also, after some number of generations, it just stops getting better. For example, in first 100 generations, it found the largest circle with radius 104. And in next 900 largest radius is 107. And after drawing it, I see that it can grow much more.
Here is my code connected with GA. I leave out generating random circles, decoding and drawing.
private Genome ChooseParent(Genome[] population, Random r)
{
double sumFitness = 0;
double maxFitness = 0;
for (int i = 0; i < population.Length; i++)
{
sumFitness += population[i].fitness;
if (i == 0 || maxFitness < population[i].fitness)
{
maxFitness = population[i].fitness;
}
}
sumFitness = population.Length * maxFitness - sumFitness;
double randNum = r.NextDouble() *sumFitness;
double acumulatedSum = 0;
for(int i=0;i<population.Length;i++)
{
acumulatedSum += population[i].fitness;
if(randNum<acumulatedSum)
{
return population[i];
}
}
return population[0];
}
private void Crossover(Genome parent1, Genome parent2, Genome child1, Genome child2, Random r)
{
double d=r.NextDouble();
if(d>this.crossoverRate || child1.Equals(child2))
{
for (int i = 0; i < parent1.bitNum; i++)
{
child1.bit[i] = parent1.bit[i];
child2.bit[i] = parent2.bit[i];
}
}
else
{
int cp = r.Next(parent1.bitNum - 1);
for (int i = 0; i < cp; i++)
{
child1.bit[i] = parent1.bit[i];
child2.bit[i] = parent2.bit[i];
}
for (int i = cp; i < parent1.bitNum; i++)
{
child1.bit[i] = parent2.bit[i];
child2.bit[i] = parent1.bit[i];
}
}
}
private void Mutation(Genome child, Random r)
{
for(int i=0;i<child.bitNum;i++)
{
if(r.NextDouble()<=this.mutationRate)
{
child.bit[i] = (byte)(1 - child.bit[i]);
}
}
}
public void Run()
{
for(int generation=0;generation<1000;generation++)
{
CalculateFitness(population);
System.Diagnostics.Debug.WriteLine(maxFitness);
population = population.OrderByDescending(x => x).ToArray();
//ELITIZM
Copy(population[0], newpopulation[0]);
Copy(population[1], newpopulation[1]);
for(int i=1;i<this.populationSize/2;i++)
{
Genome parent1 = ChooseParent(population, r);
Genome parent2 = ChooseParent(population, r);
Genome child1 = newpopulation[2 * i];
Genome child2 = newpopulation[2 * i + 1];
Crossover(parent1, parent2, child1, child2, r);
Mutation(child1, r);
Mutation(child2, r);
}
Genome[] tmp = population;
population = newpopulation;
newpopulation = tmp;
DekodePopulation(population); //decoding and fitness calculation for each member of population
}
}
If someone can point on potential problem that caused such behaviour and ways to fix it, I'll be grateful.
Welcome to the world of genetic algorithms!
I'll go through your issues and suggest a potential problem. Here we go:
maximum fitness does not always grow in the next generation, but becomes smallest - You probably meant smaller. This is weird since you employed elitism, so each generation's best individual should be at least as good as in the previous one. I suggest you check your code for mistakes because this really should not happen. However, the fitness does not need to always grow. It is impossible to achieve this in GA - it's a stochastic algorithm, working with randomness - suppose that, by chance, no mutation nor crossover happens in a generation - then the fitness cannot improve to the next generation since there is no change.
after some number of generations, it just stops getting better. For example, in first 100 generations, it found the largest circle with radius 104. And in next 900 largest radius is 107. And after drawing it, I see that it can grow much more. - this is (probably) a sign of a phenomenon called premature convergence and it's, unfortunately, a "normal" thing in genetic algorithm. Premature convergence is a situation when the whole population converges to a single solution or to a set of solutions which are near each other and which is/are sub-optimal (i.e. it is not the best possible soluion). When this happens, the GA has a very hard time escaping this local optimum. You can try to tweak the parameters, especially the mutation probability, to force more exploration.
Also, another very important thing that can cause problems is the encoding, i.e. how is the bit string mapped to the circle. If the encoding is much too indirect, it can lead to poor performance of the GA. GAs work when there are some building blocks in the genotype which can be exchanged between among the population. If there are no such blocks, the performance of a GA is usually going to be poor.
I have implemented this exercise and achieved good results. Here is the link:
https://github.com/ManhTruongDang/ai-junkie
Hope this can be of use to you.

intersection is not happening sometimes

I am doing with following code, where samosarect is one object which coming from right to left with some speed(suppose 10px per loop), tonguerect is my player's tongue which increases up to 200 width and again decreases to 0. Tongue only increases when tongue is true,tongue boolean becomes true when I press shoot button.So my problem is sometimes my player(tonguerect) don't eat(doesnt intersect with samosarect) the samosa(I watch with my eyes that rectangles are intersecting but my code is not getting that),sometimes it(intersecting with proper anim ) eats the samosa without any problem.
if (Texture.samosarect.Contains(Texture.tonguerect) || Texture.tonguerect.Intersects(Texture.samosarect) && tongue)
{
Texture.tonguerect.Y = -50;
System.Diagnostics.Debug.WriteLine("eated samosaaa");
Texture.samosarect.X = -400;
eateds = true;
jumpframe = 17;
tonguereached = true;
caught = true;
if (MainPage.togkey == 1)
eateffect.Play();
if (!catchedd)
{
score += 30; catched++; catchedd = true;
showpoint = true;
}
else { catchedd = false; }
}
For general case, this or this can help you.
Algorithm is described here.
If to talk exactly about xna, take a look here
if (ballRect.Intersects(bat1Rect))
{
ballVelo.X = Math.Abs(ballVelo.X) * -1;
}
if (ballRect.Intersects(bat2Rect))
{
ballVelo.X = Math.Abs(ballVelo.X);
}

Firmata servo control

I am stuck on my project at the final part which is controlling a servo by reading xml feed and depending on the values it should turn several degrees. I am using a weather xml feed by yahoo which shows different wind speed attributes as speed, direction and etc. What i am doing is Im using only wind direction and speed in order to visualize it with LED's and and arrow for the direction. Everything works fine with the LED's , but when it comes to the servo I'm not quite sure what to do. It works alright with the Arduino sweeping example, but I use Firmata and i guess the code for it is a bit different. First I used standard Firmata to control the LED's but it wasn't good with the servo, so now Im using 2 arduino's one with Standard Firmata for the LEDs and one with Servo Firmata for the servo, noth assigned on different COM ports. Unfortunately when I try to program the servo it only gets faster or slower without being able to control the angle of it and when to stop. In arduino it works with their example, but in Firmata it seems that I can't adapt it so it does similar in Processing with Firmata. I've been stuck on this for 2 days already pls any help would be appreciated since I have to finish it by Monday
here is the code :
import processing.serial.*;
import cc.arduino.*;
Arduino arduino, arduino2;
final String URL = "http://weather.yahooapis.com/forecastrss?w=27764362";
final String WORD = "yweather:wind";
final String TOKEN = "\\W+";
int ledPin = 13;
int ledPin1 = 12;
int ledPin2 = 8;
int pos=0;
void setup() {
arduino = new Arduino(this, Arduino.list()[0], 57600);
arduino2 = new Arduino(this, Arduino.list()[1], 57600);
arduino.pinMode(ledPin, Arduino.OUTPUT);
arduino.pinMode(ledPin1, Arduino.OUTPUT);
arduino.pinMode(ledPin2, Arduino.OUTPUT);
arduino2.pinMode (9, Arduino.OUTPUT);
final String[] xml = loadStrings(URL);
int idx = 0;
for (; idx != xml.length; ++idx)
if ( xml[idx].contains(WORD) ) break;
if (idx == xml.length) {
println("Not found");
exit();
}
println("Index: " + idx);
println(xml[idx]);
final int[] info = int( xml[idx].split(TOKEN) );
final int dir = info[6];
final int spd = info[8];
println("Speed: " + spd);
println("Direction: " + dir);
if (spd < 5 ) {
arduino.digitalWrite(ledPin, Arduino.LOW);
arduino.digitalWrite(ledPin1, Arduino.LOW);
arduino.digitalWrite(ledPin2, Arduino.LOW);
}
if (spd >= 5 && spd <10) {
arduino.digitalWrite(ledPin, Arduino.HIGH);
arduino.digitalWrite(ledPin1, Arduino.LOW);
arduino.digitalWrite(ledPin2, Arduino.LOW);
}
if (spd >= 10 && spd <= 15) {
arduino.digitalWrite(ledPin, Arduino.HIGH);
arduino.digitalWrite(ledPin1, Arduino.HIGH);
arduino.digitalWrite(ledPin2, Arduino.LOW);
}
if (spd > 16) {
arduino.digitalWrite(ledPin, Arduino.HIGH);
arduino.digitalWrite(ledPin1, Arduino.HIGH);
arduino.digitalWrite(ledPin2, Arduino.HIGH);
}
println("3");
if (dir >= 10 && dir <= 25) {
println("4");
arduino2.analogWrite(9, 90);
delay(1500);
}
else if (dir > 340 && dir <= 360) {
println("Low speed");
arduino2.analogWrite(9, 80); //in this case 80 is controlling the speed, although I wanted to control the angle
delay(1500);
arduino2.analogWrite(9, 120); // same here
delay(1500);
println("5");
}
}
All those prinLn(1-5) are obviously just code checkers to see if there is something wrong with it, but i guess there isnt, its just that i cant control the angle or any other particular control over it other than it's speed, but it doesn't stop spinning till I unplug the usb most cases :)
I guess i need to insert somewher this part of the arduino example to make it move properly :
void loop()
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
But not quite sure since i tried, but I might not have programmed it properly .
Thanks!
setup() is only called once at initialization of the sketch. loop() is repeatedly called during the runtime. therefore, most of your code needs to be in the loop.
i do recommend starting off with some simple sketches to get things running step by step.
ladyada has some good tutorials up, i.e. for serial communication at http://www.ladyada.net/learn/arduino/lesson4.html
the firmata repository holds some good examples at https://github.com/firmata/arduino/tree/master/examples
in addition, the arduino forum reveals some discussion on searching for "firmata" at http://forum.arduino.cc/

AS3 - Comparing BitmapDatas, fastest method?

Right, so let's say I want to compare two BitmapDatas. One is an image of a background (not solid, it has varying pixels), and another is of something (like a sprite) on top of the exact same background. Now what I want to do is remove the background from the second image, by comparing the two images, and removing all the pixels from the background that are present in the second image.
For clarity, basically I want to do this in AS3.
Now I came up with two ways to do this, and they both work perfectly. One compares pixels directly, while the other uses the BitmapData.compare() method first, then copies the appropriate pixels into the result. What I want to know is which way is faster.
Here are my two ways of doing it:
Method 1
for (var j:int = 0; j < layer1.height; j++)
{
for (var i:int = 0; i < layer1.width; i++)
{
if (layer1.getPixel32(i, j) != layer2.getPixel32(i, j))
{
result.setPixel32(i, j, layer2.getPixel32(i, j));
}
}
}
Method 2
result = layer1.compare(layer2) as BitmapData;
for (var j:int = 0; j < layer1.height; j++)
{
for (var i:int = 0; i < layer1.width; i++)
{
if (result.getPixel32(i, j) != 0x00000000)
{
result.setPixel32(i, j, layer2.getPixel32(i, j));
}
}
}
layer1 is the background, layer2 is the image the background will be removed from, and result is just a BitmapData that the result will come out on.
These are very similar, and personally I haven't noticed any difference in speed, but I was just wondering if anybody knows which would be faster. I'll probably use Method 1 either way, since BitmapData.compare() doesn't compare pixel alpha unless the colours are identical, but I still thought it wouldn't hurt to ask.
This might not be 100% applicable to your situation, but FWIW I did some research into this a while back, here's what I wrote back then:
I've been meaning to try out grant skinners performance test thing for a while, so this was my opportunity.
I tested the native compare, the iterative compare, a reverse iterative compare (because i know they're a bit faster) and finally a compare using blendmode DIFFERENCE.
The reverse iterative compare looks like this:
for (var bx:int = _base.width - 1; bx >= 0; --bx) {
for (var by:int = _base.height - 1; by >= 0; --by) {
if (_base.getPixel32(bx, by) != compareTo.getPixel32(bx, by)) {
return false;
}
}
}
return true;
The blendmode compare looks like this:
var test:BitmapData = _base.clone();
test.draw(compareTo, null, null, BlendMode.DIFFERENCE);
var rect:Rectangle = test.getColorBoundsRect(0xffffff, 0x000000, false);
return (rect.toString() != _base.rect.toString());
I'm not 100% sure this is completely reliable, but it seemed to work.
I ran each test for 50 iterations on 500x500 images.
Unfortunately my pixel bender toolkit is borked, so I couldn't try that method.
Each test was run in both the debug and release players for comparison, notice the massive differences!
Complete code is here: http://webbfarbror.se/dump/bitmapdata-compare.zip
You might try a shader that would check if two images are matching, and if not, save one of image's point as output. Like this:
kernel NewFilter
< namespace : "Your Namespace";
vendor : "Your Vendor";
version : 1;
description : "your description";
>
{
input image4 srcOne;
input image4 srcTwo;
output pixel4 dst;
void evaluatePixel()
{
float2 positionHere = outCoord();
pixel4 fromOne = sampleNearest(srcOne, positionHere);
pixel4 fromTwo = sampleNearest(srcTwo, positionHere);
float4 difference=fromOne-fromTwo;
if (abs(difference.r)<0.01&&abs(difference.g)<0.01&&abs(difference.b)<0.01) dst=pixel4(0,0,0,1);
else dst = fromOne;
}
}
This will return black pixel if matched and first image's pixel when no match. Use Pixel Bender to make it run in Flash. Some tutorial is here. Shaders are usually a factor faster than plain AS3 code.

Resources