Creating an If statement for an entire array - arrays

So here is my situation. I'm new to programming and I've just started making a very, very basic platform game. And I mean literally a game with platforms.
I've got my character in and jumping about and I've created my platforms as an array. This was so that I could put them all side by side at the bottom. Now there is other ways I can do this to get round the problem but I wanted to find out how to do it for an array.
So I've got my character falling with this
kirby.yVelocity += 1.0f
Which is all fine but I want his yVelocity to go to 0.0f when he hits any of the platforms in the array.
So I tried this piece of code
if (plat[i].drawRect.Intersects(kirby.drawRect))
{
kirby.yVelocity = 0.0f
}
which I thought would work but it gives me an error for the [i] saying that it isn't applicable in this context.
few notes:
kirby is my character name, drawRect is the definition for Rectangle, plat is my Platform array which consists of 13 platforms.
Thanks to anyone who can help
Update
The problem is any variation of plat.drawRect or plat[i].drawRect don't work. Here is all my code relating to the platform arrays.
struct Platform
{
public Texture2D txr;
public Rectangle drawRect;
}
Platform[] plat;
plat = new Platform[13];
for (int i = 0; i < plat.Length; i++)
{
plat[i].txr = Content.Load<Texture2D>("platform");
plat[i].drawRect = new Rectangle(i * plat[i].txr.Width, 460, plat[i].txr.Width, plat[i].txr.Height);`
}
for (int i = 0; i < plat.Length; i++)
{
spriteBatch.Draw(plat[i].txr, plat[i].drawRect, Color.White);
}
spriteBatch.End();

Seems like you have to add a for loop, to loop over the platforms. Maybe like this:
for(Platform : plat){
if (platform.drawRect.Intersects(kirby.drawRect)){
kirby.yVelocity = 0.0f;
}
}
Here, I'm assuming you're using Java and Platform is the class of your plat-array, which has class List<Platform>.

Related

How to create a world map using C language?

How to create a world map using C language?
Here, I want to generate a 1000*1000 two dimensional array of world map. Within the array, the land part is marked with value 1 and the sea part is marked with value 0. Is there any simple way to create?
Obviously, there's no algorithm which describes the shape of the coastline of the continents ;)
But you could use e.g. Smrender (http://www.abenteuerland.at/smrender/), feed it with the coastline of e.g. OpenStreetMap or Naturalearthdata and a single rule. Let it create a PNG image with 1000x1000 pixels.
EDIT:
With ImageMagick (convert) you can directly convert a PNG into a C header file as an array.
Go to Openstreetmap.org (or Googlemaps), zoom out until you see the whole world, make a screenshot, open it in your favorite image manipulation program and cut and resize it to 1000x1000, then run convert input.png output.h.
Bernhard
I wrote a answer in game development some hours ago that can help you, heres the topic, it's written in javascript, but it won't be hard to translate to c.
In the example you fill the whole map of 0's and then you trace a path randomly, if you want to smooth the map later you can make a snippet that loops all the watter tiles and converts them to land if there are 3 or more land tiles adjacent to it, do it 40-60 times and you will get a smoother shore and no "holes" in the continent.
EDIT
Updating the answer with a demo in C.
I've not tested it, but if you include the headers and checks the code, this is the answer.
//Create and populate the map
int mapsize = 100;
int map[mapsize*mapsize];
for(int t = 0; t < mapsize*mapsize; t++) map[t] = 0;
//make the path
int currPos[2] = {0,50};
map[currPos[0]+(currPos[1]*mapSize)] = 1;
int landTiles = 20000;
for(var l = 0; l < landTiles; l++){
int dir[2] = {RANDOM_BETWEEN_-1_AND_1, RANDOM_BETWEEN_-1_AND_1};
int next[2] = {currPos[0]+dir[0], currPos[1]+dir[1]};
map[next[0]+(next[1]*mapSize)] = 1;
currPos = next;
}
//Draw the map
for(var row = 0; row < mapSize; row++){
for(var col = 0; col < mapSize; col++){
cout << map[col+(row*mapSize)];
}
cout << endl;
}
You could have some program or script (taking as input some representation of some image of the Earth) which generates a long C file like
const char map[1000][1000] = {
{'0', '1', //.... etc for the first fow
},
{'0', '0', '0', '1', //... etc
}
/// etc for other rows
};
See also XBM for an example.

Bug in Resilient Backpropagation?

I'm struggling with implementing Resilient Propagation correctly. I already implemented the backpropagation Algorithm to train a Neural Network, and it works as expected for an XOR-Net, i.e. it takes about 600 Epochs to drop Error below 1%. Now i tried implementing Resilient Propagation (http://en.wikipedia.org/wiki/Rprop) for the same problem and for the first few Epochs Error drops quickly to 23% but then raises to 50% and stays there.
I implemented it exactly as per description in http://www.heatonresearch.com/book/introduction-neural-network-math.html, but that's a puzzling Description: it's different from the wikipedia Rprop-Page AND from the implementation in encog, which was written by the same author as the book, as far as i know.
I also already tried the different implementations from the different sources, but nothing worked.
Some of the differences between the various sources:
using signum(currentPartialDerivative) instead of signum(currentPartialDerivative * previousPartialDerivative) for the calculation of the weight-changes
using the last weight change, instead of the new update value for the new weight changeCalculating the weight changes firstly and the new update values secondly
What is the correct way of implementing this? Subsequently the Implementation according to the book:
public ResilientPropagation() {
initialUpdateValue = 0.01;
deltaMaximum = 50;
deltaMinimum = 0.000001;
negativeEta = 0.5;
positiveEta = 1.2;
double zeroTolerance = 0.0000000000000001;
signum = new Signum(zeroTolerance);
init();
}
#Override
public double calculateWeightChange(Synapse synapse, double partialDerivative) {
if (!synapseValues.containsKey(synapse)){
double initialPartialDerivative = 0;
synapseValues.put(synapse, new SynapseValues(initialUpdateValue, initialPartialDerivative));
}
SynapseValues values = synapseValues.get(synapse);
double signChange = signum.value(values.lastPartialDerivative * partialDerivative);
values.lastPartialDerivative = partialDerivative;
double weightChange = 0;
if (signChange > 0){
newUpdateValue = Math.min(positiveEta * values.updateValue, deltaMaximum);
weightChange = -1*newUpdateValue;
} else if (signChange < 0){
newUpdateValue = Math.max(negativeEta * values.updateValue, deltaMinimum);
weightChange = newUpdateValue;
} else {
newUpdateValue = values.updateValue;
double weightChange = 0;
}
values.updateValue = newUpdateValue;
return weightChange;
}
The same Method for normal Backpropagation works fine:
#Override
public double calculateWeightChange(Synapse synapse, double partialDerivative) {
double previousChange = previousWeightChange.get(synapse) != null ? previousWeightChange.get(synapse) : 0;
double weightChange = learningRate * partialDerivative + momentum * previousChange;
previousWeightChange.put(synapse, weightChange);
return weightChange;
}
There are several different variants of the RPROP algorithm. Encog has been modified to support more of them since the publication of the book. The book focuses on the classic RPROP, as defined by a paper by Reidmiller. Subsequent papers made additional algorithms. This accounts for some differences between Encog's optimized RPROP algorithm and what the book describes.
Looking at your code above, I have a few suggestions that might help. Mostly I am not sure about your final else clause. You have "double weightChange = 0", which will do nothing. I think you need to remove the double. You also need to establish some tolerance for what "zero" is. The change in gradients will rarely precisely hit zero, so I would establish some range about zero, maybe -0.00001 to +0.00001 for the else clause to fire. Then make sure you actually set weightChange to zero.
Another issue that I recall from my own rprop implementation was that the sign of the gradient used for backpropagation was the inverse sign of the gradient used for backpropagation. You might try flipping the sign of the gradient for RPROP, this was necessary in my Encog implementation.
This implementation of RPROP might be useful for you, it is the classic Reidmiller implemenation. It does function correctly and the error converges.
https://github.com/encog/encog-java-core/blob/master/src/main/java/org/encog/neural/freeform/training/FreeformResilientPropagation.java
Not sure if this will help. Without running the code, this is all that I see.

hitTestPoint or hitTestObject?

I'm needing to make my character land on a ledge and stay there, but it only keeps going straight through it. Would I create an array for all my different ledges and test whenever my character hits them? Any help would be appreciated.
Thanks.
Collision detection for floors and stuff is actually alot diffrent from hitTesting in the idea that needs to consistently see that the objects are touching. Try something like this!
//loop through all the platform objects to generate the level
var level:Array = new Array();
for (var i=0; i<numChildren; i++)
{
if (getChildAt(i) is platform)
{
level.push(getChildAt(i).getRect(this));
}
}
for (i=0; i<level.length; i++)
{
if (player.getRect(this).intersects(level[i]))
{
if (speedX > 0) ////moving right collision and stuffs
{
player.x = level[i].left-player.width/2;
}
if (speedX < 0) ////moving left collision and stuffs
{
player.x = level[i].right+player.width/2;
}
speedX = 0 //kills the speed
}
}
speedX is the speed at which the characters move horizontally, and "platform" is the name of the variable that you're using as the cliff. Also, "player" can be substituted by whatever you are calling your object that's going onto the ledge. That's how I did it in one of my computer classes anyways :) Hope that helps!

How to draw a polygon from a set of unordered points

Currently, I am using a convex hull algorithm to get the outer most points from a set of points randomly placed. What I aim to do is draw a polygon from the set of points returned by the convex hull however, when I try to draw the polygon it looks quite strange.
My question, how do I order the points so the polygon draws correctly?
Thanks.
EDIT:
Also, I have tried sorting using orderby(...).ThenBy(...) and I cant seem to get it working.
Have you tried the gift wrapping algorithm ( http://en.wikipedia.org/wiki/Gift_wrapping_algorithm)? This should return points in the correct order.
I had an issue where a random set of points were generated from which a wrapped elevation vector needed a base contour. Having read the link supplied by #user1149913 and found a sample of gift-wrapping a hull, the following is a sample of my implementation:
private static PointCollection CalculateContour (List<Point> points) {
// locate lower-leftmost point
int hull = 0;
int i;
for (i = 1 ; i < points.Count ; i++) {
if (ComparePoint(points[i], points[hull])) {
hull = i;
}
}
// wrap contour
var outIndices = new int[points.Count];
int endPt;
i = 0;
do {
outIndices[i++] = hull;
endPt = 0;
for (int j = 1 ; j < points.Count ; j++)
if (hull == endPt || IsLeft(points[hull], points[endPt], points[j]))
endPt = j;
hull = endPt;
} while (endPt != outIndices[0]);
// build countour points
var contourPoints = new PointCollection(points.Capacity);
int results = i;
for (i = 0 ; i < results ; i++)
contourPoints.Add(points[outIndices[i]]);
return contourPoints;
}
This is not a full solution but a guide in the right direction. I faced a very similar problem just recently and I found a reddit post with an answer (https://www.reddit.com/r/DnDBehindTheScreen/comments/8efeta/a_random_star_chart_generator/dxvlsyt/) suggesting to use Delaunay triangulation which basically returns a solution with all possible triangles made within the data points you have. Once you have all possible triangles, which by definition you know won't result on any overlapped lines, you can chose which lines you use which result on all nodes being connected.
I was coding my solution on python and fortunately there's lots of scientific libraries on python. I was working on a random sky chart generator which would draw constellations out of those stars. In order to get all possible triangles (and draw them, just for fun), before going into the algorithm to draw the actual constellations, all I had to do was this:
# 2D array of the coordinates of every star generated randomly before
points = list(points_dict.keys())
from scipy.spatial import Delaunay
tri = Delaunay(points)
# Draw the debug constellation with the full array of lines
debug_constellation = Constellation(quadrants = quadrants, name_display_style = config.constellation_name_display_style)
for star in available_stars:
debug_constellation.add_star(star)
for triangle in tri.simplices:
star_ids = []
for index in triangle:
star_ids.append(points_dict[points[index]].id)
debug_constellation.draw_segment(star_ids, is_closed = True)
# Code to generate the image follows below
You can see the full implementation here: fake_sky_chart_generator/fake_libs/constellation_algorithms/delaunay.py
This is the result:

multiple instances of the same object spaced out using a loop is only creating one

I had a hard time trying to word my question properly, so i'm sorry if it seems confusing. Also i'm using the flixel library in flash builder. It may not be that important butcause probably anyone that knows a little more than me or even a little AS3 could probably see what i'm doing wrong.
Anyway, what i'm trying to do is basically create 10 instances of this square object I made. all I have to do is pass it an x an y coordinate to place it and it works. so ive tested if i just do:
var testsquare:Bgsq;
testsquare = new Bgsq(0,0);
add(testsquare);
it works fine and adds a square at 0,0 just like i told it to, but i want to add 10 of them then move the next one that's created 25 px to the right (because each square is 25px)
my problem is that I only ever see 1 square, like it's only making 1 instance of it still.
anyone possibly have an idea what I could be doing wrong?
var counter:int = 0;
var bgsqa:Array = new Array;
for (var ibgs:int = 0; ibgs < 10; ibgs++)
{
bgsqa[counter] = new Bgsq(0,0);
bgsqa[counter].x += 25;
add(bgsqa[counter]);
counter++;
}
There's a lot you're doing wrong here.
First off, you're using a pseudo-iterator (counter) to access array elements through a loop instead of, well, using the iterator (ibgs).
Second, I don't see anything in the array (bgsqa) you're iterating through. It's no wonder you're having problems. Here's what you should do.
var bgsqa:Array = [];
for(var i:int=0;i<10;i++)
{
var bgsq:Bgsq = new Bgsq(i * 25, 0);
add(bgsq);
bgsqa.push(bgsq);
}
That should probably do it if your post is accurate.
for (var ibgs:int = 0; ibgs < 10; ibgs++)
{
bgsqa[counter] = new Bgsq(0,0);
bgsqa[counter].x = counter * 25;
add(bgsqa[counter]);
counter++;
}
They start at 0, so applying += is simply adding 25 to 0. This should do the trick.

Resources