Ok, I've got a weird one here. I'm trying to make a basic tile engine using a windows form, but some of my code is just...not happening. I'll post the chunks in question.
private void MapEditor_Load(object sender, EventArgs e)
{
LoadImageList();
FixScrollBarScales();
cboCodeValues.Items.Clear();
cboCodeValues.Items.Add("ENEMY");
cboCodeValues.Items.Add("CHEST");
cboCodeValues.Items.Add("NPC");
for (int x = 0; x < 100; x++)
cboMapNumber.Items.Add(x.ToString().PadLeft(3, '0'));
cboMapNumber.SelectedIndex = 0;
TileMap.EditorMode = true;
backgroundToolStripMenuItem.Checked = true;
}
This should be called when the form loads, right? The code dives into LoadImageList(), which contains:
private void LoadImageList()
{
string filepath = Application.StartupPath +
#"\Content\Textures\IndoorTileSet.png";
Bitmap tileSheet = new Bitmap(filepath);
int tilecount = 0;
for(int y = 0; y < tileSheet.Height / TileMap.TileHeight; y++)
{
for(int x = 0; x < tileSheet.Width / TileMap.TileWidth; x++)
{
Bitmap newBitmap = tileSheet.Clone(
new System.Drawing.Rectangle(
x * TileMap.TileWidth,
y * TileMap.TileHeight,
TileMap.TileWidth,
TileMap.TileHeight),
System.Drawing.Imaging.PixelFormat.DontCare);
imgListTiles.Images.Add(newBitmap);
string itemName = "";
if(tilecount == 0)
itemName = "Empty";
if(tilecount == 1)
itemName = "Floor";
listTiles.Items.Add(new ListViewItem(itemName, tilecount++));
}
}
}
The bitmap loads correctly, but then the entire MapEditor_Load method just stops working. tileCount seems to be a local variable in the debugger, and its value is 0, but the debugger never executes the breakpoint on the line which it is assigned. I have absolutely no idea why it would do this, and it's driving me nuts. Any help?
Oh, I put the bitmap load in a try/catch block just to see if it was handling an exception in a weird way, but I had no luck. It's not throwing an exception. I began having this problem immediately after replacing my IndoorTileSet with an updated version. I've tried a clean rebuild, with no success.
I read something about a person having a similar problem, who wound up having to declare something as an Instance of a class, but the post wasn't detailed enough for me to know if that's where I'm going wrong, or what I might have to declare as an Instance for it to work...or what an Instance even means, really.
I'm not sure about the code in LoadImageList() method but I suggest you to use BackgroundWorker or Control.Invoke to make your application more responsive.
Try this :
Bitmap tileSheet = (Bitmap)Bitmap.FromFile(filepath);
The problem is, superficially, that my Bitmap code is throwing an FileNotFound exception, which means I've got a bad filepath. I can handle that. The issue of the program not actually throwing exceptions, and seeming to ignore code, is an issue with 64-bit operating systems not being able to handle exception calls in all instances. The details, and a link to a hotfix to solve the issue, can be found at this site.
Related
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!
I am trying to write a program that will recognize an image on the screen, compare it against a resource library, and then calculate based on the result of the image source.
The first thing that I did was to create the capture screen function which looks like this:
private Bitmap Screenshot()
{
System.Drawing.Bitmap Table = new System.Drawing.Bitmap(88, 40, PixelFormat.Format32bppArgb);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(RouletteTable);
g.CopyFromScreen(1047, 44, 0, 0, Screen.PrimaryScreen.Bounds.Size);
return Table;
}
Then, I analyze this picture. The first method I used was to create two for loops and analyze both the bitmaps pixel by pixel. The problem with this method was time, it took a long time to complete 37 times. I looked around and found the convert to bytes and the convert to hash methods. This is the result:
public enum CompareResult
{
ciCompareOk,
ciPixelMismatch,
ciSizeMismatch
};
public CompareResult Compare(Bitmap bmp1, Bitmap bmp2)
{
CompareResult cr = CompareResult.ciCompareOk;
//Test to see if we have the same size of image
if (bmp1.Size != bmp2.Size)
{
cr = CompareResult.ciSizeMismatch;
}
else
{
//Convert each image to a byte array
System.Drawing.ImageConverter ic = new System.Drawing.ImageConverter();
byte[] btImage1 = new byte[1];
btImage1 = (byte[])ic.ConvertTo(bmp1, btImage1.GetType());
byte[] btImage2 = new byte[1];
btImage2 = (byte[])ic.ConvertTo(bmp2, btImage2.GetType());
//Compute a hash for each image
SHA256Managed shaM = new SHA256Managed();
byte[] hash1 = shaM.ComputeHash(btImage1);
byte[] hash2 = shaM.ComputeHash(btImage2);
for (int i = 0; i < hash1.Length && i < hash2.Length&& cr == CompareResult.ciCompareOk; i++)
{
if (hash1[i] != hash2[i])
cr = CompareResult.ciPixelMismatch;
}
}
return cr;
}
After I analyze the two bitmaps in this function, I call it in my main form with the following:
Bitmap Table = Screenshot();
CompareResult success0 = Compare(Properties.Resources.Result0, Table);
if (success0 == CompareResult.ciCompareOk)
{ double result = 0; Num.Text = result.ToString(); goto end; }
The problem I am getting is that once this has all been accomplished, I am always getting a cr value of ciPixelMismatch. I cannot get the images to match, even though the images are identical.
To give you a bit more background on the two bitmaps, they are approximately 88 by 40 pixels, and located at 1047, 44 on the screen. I wrote a part of the program to automatically take a picture of that area so I did not have to worry about the wrong location or size being captured:
Table.Save("table.bmp");
After I took the picture and saved it, I moved it from the bin folder in the project directly to the resource folder and ran the program again. Despite all of this, the result is still ciPixelMismatch. I believe the problem lies within the format that the pictures are being saved as. I believe that despite them being the same image, they are being analyzed in different formats, maybe one of the pictures contains a bit more information than the other which is causing the mismatch. Can somebody please help me solve this problem? I am just beginning with my c# programming, I am 5 days into the learning process, and I am really at a loss for this.
Yours sincerely,
Samuel
I know there are quite similar questions here, but I haven't found the proper details. What would be helpful is definitely an explanation of the problems, and perhaps a base example, that anyone who searches later may be able to apply. (Not asking that you write it for me, I just find the examples helpful) I don't want to upset anyone and am kind of worried to post in a forum...
I am wondering alternatives to creating a screen based off tiles created from an array. I have been having an issue myself trying to access the movieclips that have been placed on screen, and trying to trace to find a way to reference them hasn't been working.
Anyway, take something basic like an array, and connecting it to movieclips, then how to access the movieclip itself once done. So I have been working on this, and used many different online resources, so I'm sure a lot of this is going to look familiar, just in a much messier way.
This takes the array to make the movieclips appear (Im sure at least one part in here is unnecessary, and I'm thinking I'm doing something wrong here that makes it not work out later) So this works, but feels pretty bulky.
Both are from the same main class file.
function makeWorld (anyMap, tileW, tileH) {
var worldWidth = anyMap[0].length;
var worldHeight = anyMap.length;
var MAP = this.addChild(new mapHolder());
function tiler(MAP, i, j, tileW, tileH, tile)
{
MAP.addChild(tile);
tile.x = (j * tileW);
tile.y = (i * tileH);
}
for (var i = 0; i < worldWidth; ++i) {
for (var j = 0; j < worldHeight; ++j) {
var curTile:int = anyMap[i][j];
if (curTile == 101) {
var tile1 = new tileGround();
tiler (MAP, i, j, tileW, tileH, tile1);
...
else {
var tile3 = new empty();
tiler (MAP, i, j, tileW, tileH, tile3);
}
}}}
Then there is attempting to reference it, where I'm having the issue. I don't know what to call this.MAP.tileGround by, and I have tried many things. I've read it's not such a good idea to reference by name when not very advanced so I wanted to avoid that sort of thing too.
addEventListener (Event.ENTER_FRAME, hits);
function hits (event:Event) {
var tileCatchG:MovieClip = this.MAP.tileGround;
if(tileCatchG.hitTestPoint(this.MAP.Char.x + leftBumpPoint.x, this.MAP.Char.y + leftBumpPoint.y, true)){
leftBumping = true;
} else {
leftBumping = false;
}
...
}
Thank you!
In looking over what you're doing a second time it would appear that you should have a reference to the 2-indexed array that represents the map.
You can create a regular (single indexed) Array at the top of the file like
public var tileArray:Array = [];
Then where you create them push them into the array
var tile1 = new tileGround();
tileArray.push(tile1);
then to reference them all you can just run a simple loop
for each(var tile:MovieClip in tileArray)
{
//Do stuff
if(tile instanceof tileGround)
{
//Do stuff specific to tileGround
}
}
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>.
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.