GameEngine2D

Reply
Beta Tester
Linzoid
Posts: 426
Registered: ‎04-08-2006
Message 1 of 8 (580 Views)

Collisions by Pixel

I've been looking at some XNA examples to workout how I can integrate collisions into my PSS game. I've found the following code to transform a texture into a 2D array. However I've not yet been successful in recreating this in the PSS.

 

private Color[,] TextureTo2DArray(Texture2D texture)
{
Color[] colors1D = new Color[texture.Width * texture.Height];
texture.GetData(colors1D);

Color[,] colors2D = new Color[texture.Width, texture.Height];
for (int x = 0; x < texture.Width; x++)
for (int y = 0; y < texture.Height; y++)
colors2D[x, y] = colors1D[x + y * texture.Width];

return colors2D;
}

 

Does anyone have any example code that can do pixel based collisions within the GameEngine2D?

Please use plain text.

Level 2

Level 2
JWordsworth
Posts: 16
Registered: ‎22-04-2012
Message 2 of 8 (561 Views)

Re: Collisions by Pixel

It feels like it's going around the houses a little - but I can't see any way of grabbing texture data from a Texture2D or PixelBuffer object directly, so you might want to also load up the texture using the 'Image' object, which will give you access to the pixel data before loading up the Texture object. This is untested, but off the top of my head - something like the following might be an option;

 

// Note. I'm making an assumption that all images you read in are 'ImageMode.RGBA' as I believe Image objects are either RGBA or just A. This is completely untested, and it just a potential idea for a solution.

 

---------

 

String filePath = "/Application/assets/image.png";

Image image = new Image(filePath);

Byte[] byteData = image.ToBuffer();

image.Dispose();

 

Texture2D texture = new Texture(byteData, false, PixelFormat.Rgba);

 

if ( byteData.Length > 0 ) {

  Byte[] alphaChannelData = new Byte[byteData.Length / 4];

  

  for ( int i = 0; i < alphaChannelData.Length; i++ )

  {

    alphaChannelData[i] = byteData[i*4];

  }

}

 

--------

 

This *should* pull out the alpha channel when you load a sprite and you could store and use that alphaChannelData (1 byte per pixel) in your per-pixel collision detection routine later on. There are possibly (probably) better alternatives available, but this is what comes to mind after the limited time I've been playing with the SDK.

 

With this in mind however, I don't know how much much juice the PS Vita / PSS devices are realistically going to have for per-pixel collision detection. I coded up a PP Collision Detection routine using XNA and even using a system to pull out the intersecting rectangle first, the operation was rather expensive in terms of CPU power. You might want to consider a shape system and/or using the Physics2D library - even if you only use it with 'triggers' (collision detection).

Please use plain text.
Beta Tester
Linzoid
Posts: 426
Registered: ‎04-08-2006
Message 3 of 8 (553 Views)

Re: Collisions by Pixel

Thanks for the reply, I'll give your example a try. I really am surprised that the GameEngine2D doesn't have a standard collision system included.

I've had a look at the ActionGameDemo and that uses a shape based collision system, so I could use that or potentially the Physics2D library as you suggested.

thanks again for your help.

Please use plain text.
Beta Tester
Linzoid
Posts: 426
Registered: ‎04-08-2006
Message 4 of 8 (550 Views)

Re: Collisions by Pixel

I've just tested the above code and it appears that the ToBuffer() method doesn't seem to work. During debugging I notcied that when I hover over the ToBuffer() method the IDE sates that it's an "Unknown Member". It also returns an empty byte array.

I had a quick look at the ToBuffer() method in the Assembly Browser and it uses another method called GetPixelData, see below. I cannot find any reference to GetPixelData anywhere?

using System;
using System.Security;
[SecuritySafeCritical ]
public byte[] ToBuffer ()
{
uint num2;
int num = Image.GetPixelDataSize (this.handle, out num2);
if (num != 0)
{
Error.ThrowNativeException (num);
}
byte[] array = new byte[(int)((UIntPtr)num2)];
num = Image.GetPixelData (this.handle, array, num2);
if (num != 0)
{
Error.ThrowNativeException (num);
}
return array;
}
Please use plain text.

Level 2

Level 2
JWordsworth
Posts: 16
Registered: ‎22-04-2012
Message 5 of 8 (532 Views)

Re: Collisions by Pixel

Hmm, this looks more complicated than I thought it would be (but possibly only because things are in Beta stage and not 100% yet).

 

* ActionGameDemo *

 

I've only had a very brief look at the ActionGameDemo, but it looks like every frame each entity adds itself to the 'collider'. Then, the EntityCollilder simply iterates over each of the pairs of entities and does a 'distance squared' check against the radius of each object. Hence, it's modelling everything as a circle and brute force checking everything to see if it collides. If you don't have too many objects in the scene, and most of your entities are easily modelled by one or more circles, this could work ok.

 

* Physics2D Library *

 

I'm looking at the Physics2D library at the moment, as I'm trying to integrate it into my game. It looks to be quite 'heavy weight' but I'm assuming it's highly optimised. If you are creating a scene which contains 30 fixed objects and they move around - then it doesn't look too hard to get the hang of. If you are creating a model in which objects are rapidly created and destroyed (I'm trying to add bullets to my space shooter) then I've not quite figured that out yet. Removing entities from the scene looks to be a bit of a pain, as it works with a fixed length array not a list / vector. I guess I'm saying - this will probably do the trick very well, but it could be a complicated solution.

 

* Getting Pixels from an Image *

 

My first impression is that it could be that this method might not be properly supported yet in the SDK. However, this might sound obvious, but have you also checked the 'Size' property to ensure that the image is infact loading properly? I'm not sure if you might also need to call the method 'Decode()' on the object after constructing it but before using it? I'm guessing that GetPixelData is a private method on the Image object.

 

If this doesn't work, I'm a bit stuffed on what to suggest I'm afraid. It seems like the GetPixel type methods have been deliberately hidden away (unless I've missed something obvious). The only other ways I can think of achieving what you are after are...

 

1. Drawing your graphic to the Frame Buffer and using GraphicsContext.ReadPixels() to read back the pixel data from the frame buffer. You would obviously have to do all this before starting your game level as you're essentially drawing it to the screen just to get access to the pixel data.

 

2. Try to find some PNG loading library and use that to load the pixel data in.

 

3. Store shape data in text files along with the image files you make for your app / game. Then load these shapes in and write a shape based collision detection system.

 

4. Use something like the Farseer Physics Engine (http://farseerphysics.codeplex.com/), which I am thinking of attempting to make use of in our project. Farseer is based on Box2D, so there is a lot of information about how to use it (even just for collision detection).

Please use plain text.
Beta Tester
Linzoid
Posts: 426
Registered: ‎04-08-2006
Message 6 of 8 (517 Views)

Re: Collisions by Pixel

Thanks for all your help, the Decode() method is required in order to use the ToBuffer() method.

I've now managed to extract the alpha data into an array:

 

Image image = new Image(filePath);
image.Decode();
Byte[] byteData = image.ToBuffer();        
Byte[] alphaChannelData = new Byte[byteData.Length / 4];

 

if ( byteData.Length > 0 )
{   
     for ( int i = 0; i < alphaChannelData.Length; i++ )
     {
          alphaChannelData[i] = byteData[(i*4)+3]; 
     }
}

 

 

Please use plain text.

Level 3

Level 3
Daveid
Posts: 45
Registered: ‎07-04-2009
Message 7 of 8 (490 Views)

Re: Collisions by Pixel

In regards to creating and destroying bullets often why don't you have a bullets pool and reuse bullets

 

Please use plain text.

Member

Member
neo_ark_256
Posts: 1
Registered: ‎20-05-2012
Message 8 of 8 (384 Views)

Re: Collisions by Pixel

What means this code?

if ( byteData.Length > 0 )
{   
     for ( int i = 0; i < alphaChannelData.Length; i++ )
     {
          alphaChannelData[i] = byteData[(i*4)+3];
     }
}

 

Good Work

Please use plain text.
Announcements

Welcome to the PlayStation Mobile Developer Forums


This is a community for the discussion of technical topics with other developers and SCE engineers. Posting ideas/requests are also appreciated. Join the discussion!

PlayStation®Mobile開発者フォーラムでは世界中の開発者の皆様と一緒に、議論や情報交換が可能です。SCEも議論に参加し、皆様の開発をサポートします。アイデアやリクエストも大歓迎です。ぜひご参加ください。

PSM Developer Registration (for free) on PSM DevPortal is required to post on the forum.
Please sign out then sign in again to the forum and PSM DevPortal after you have completed the registration.

フォーラムへ投稿をするにはPSM DevPortalへの登録(無料)が必要です。
登録後はフォーラムと PSM DevPortalを一度ログアウトし、再度ログインしてください。