I'm working on a 2D plane dodging game and I'm having issues in Unity 5, I'm trying to stop the collision between two incoming planes, I've tried many different solutions but those don't work. I can't put them in different layers because they still need to collide with the player. This is the code I have for the first plane. Enemy and Bullets are both tags. Thanks
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletPlane : MonoBehaviour {
public float speed = 6f;
public float reloadTime = 1f;
public GameObject bulletPrefab;
public GameObject explosion;
public GameObject smoke;
public GameObject warning;
public GameObject self;
public float reloadSecond = .10f;
private float elapsedTime = 0;
public float timeElapsed = 0;
private Rigidbody2D rigidBody;
void Start()
{
rigidBody = GetComponent<Rigidbody2D> ();
rigidBody.velocity = new Vector2 (0, speed);
Vector3 warningPos = transform.position;
warningPos += new Vector3 (0, -10.5f, 0);
Instantiate (warning, warningPos, Quaternion.identity);
}
void Update() {
elapsedTime++;
Vector3 spawnPos = transform.position;
Vector3 secondPos = transform.position;
elapsedTime = 0f;
spawnPos += new Vector3 (0, -1.2f, 0);
secondPos += new Vector3 (-1, -0.9f, 0);
Instantiate (bulletPrefab, spawnPos, Quaternion.identity);
Instantiate (smoke, secondPos, Quaternion.identity);
if (elapsedTime > reloadSecond) {
spawnPos += new Vector3 (0, -1.2f, 0);
secondPos += new Vector3 (-1, -0.9f, 0);
Instantiate (bulletPrefab, spawnPos, Quaternion.identity);
Instantiate (smoke, secondPos, Quaternion.identity);
elapsedTime = 0f;
timeElapsed++;
}
}
void OnTriggerEnter2D(Collider2D other) {
if (other.gameObject.CompareTag ("Player")) {
Destroy (other.gameObject);
} else if (other.gameObject.CompareTag ("Enemy")) {
Physics2D.IgnoreCollision (other.GetComponent<Collider2D> (), gameObject.GetComponent<Collider2D> (), true);
} else if (other.gameObject.CompareTag ("Bullets")) {
Physics2D.IgnoreCollision (other.GetComponent<Collider2D> (), gameObject.GetComponent<Collider2D> (), true);
}
}
}
This is the code for the other enemy plane
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyPlane : MonoBehaviour {
public float speed = -6f;
public float reloadTime = 1f;
public GameObject bulletPrefab;
public GameObject explosion;
private float elapsedTime = 0;
private Rigidbody2D rigidBody;
void Start()
{
rigidBody = GetComponent<Rigidbody2D> ();
rigidBody.velocity = new Vector2 (0, speed);
}
void OnTriggerEnter2D(Collider2D other) {
if (other.gameObject.CompareTag ("Ally")) {
} else if (other.gameObject.CompareTag ("Enemy")) {
Physics2D.IgnoreCollision (other.GetComponent<Collider2D> (), gameObject.GetComponent<Collider2D> (), true);
} else if (other.gameObject.CompareTag ("BulletPlane")) {
Physics2D.IgnoreCollision (other.GetComponent<Collider2D> (), gameObject.GetComponent<Collider2D> (), true);
}
}
}
You still be able to set the layer, while your player can still be able to interact with.
Suppose you have 3 different objects
Plane A
Plane B
Player
and you want Plane A to don't collide with Plane B, but still collide with Player.
You can set the collision matrix on
Edit -> Project Settings -> Physics2D
How to setup?
Set Plane A to Layer 'CollideOnlyWithPlayer'
Set Player to layer 'Player'
Then in the collision matrix, you can unchek all for layer CollideOnlyWithPlayer
But check for CollideWithPlayer to Player layer
The collision matrix define how object interact within the other object in layer.
It's defined by two indices, the vertical one and the horizontal one.
When you check for example, Vertical 'Player' to Horizontal 'Player'
this means, that your player can interact with player
And when you check for example, Vertical 'Player' to Horizontal 'CollideWithPlayer'
this means that your player physic can interact with object layered to CollideWithPlayer.
Pleas see the full documentation here
https://docs.unity3d.com/Manual/LayerBasedCollision.html
Related
I would like to implement some kind of eraser,so in my render method I make the upper layer transparent.
#Override
public void render () {
cam.update();
Gdx.gl.glClearColor(1, 1, 1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (Gdx.input.isTouched()) {
pos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
pixmap.setColor(new Color(1, 1, 1, 0.5f)); //transparency
pixmap.fillCircle((int)pos.x, (int)pos.y, 10);
}
texture3.draw(pixmap, 0, 0);
batch.begin();
batch.draw(texture, 0, 0);
batch.draw(texture3, 0, 0);
batch.end();
}
But I got points when make swipes. It requires to do very slow speed to make lines instead of dots.
So I expect continuous line instead of dots.
Can you advice something please?
Dots instead of line
This is caused because of the frequency at which the input state is updated, the solution here would be to manually calculate the missing points needed to make a line, you could do this with a linear interpolation between each pair of dots, additionally you could calculate how many extra dots are necessary depending on how far is the newest dot from the previous one, in my example I use an arbitrary number of extra dots (20) like so:
public class TestDraw extends Game {
private Pixmap pixmap;
private Texture texture;
private SpriteBatch batch;
private Vector2 lastPos;
#Override
public void create() {
pixmap = new Pixmap(1000, 1000, Pixmap.Format.RGBA8888);
texture = new Texture(pixmap);
batch = new SpriteBatch();
lastPos = new Vector2();
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (Gdx.input.isTouched()) {
pixmap.setColor(new Color(1, 1, 1, 0.5f)); //transparency
int newX = Gdx.input.getX();
int newY = Gdx.input.getY();
pixmap.setColor(Color.RED);
pixmap.fillCircle(newX, newY, 10);
// If the distance is too far, fill with extra dots
if (lastPos.dst(newX, newY) > 10) { // Here far is 10, you can adjust as needed
int extraDots = 20; // How many extra dots to draw a line, I use 20, adjust as needed or calculate according to distance (for example lastPos.dst(newX,newY) * 5)
for (int i = 0; i < extraDots; i++) {
float progress = (1f / extraDots) * i;
int dotX = (int) MathUtils.lerp(lastPos.x, newX, progress);
int dotY = (int) MathUtils.lerp(lastPos.y, newY, progress);
pixmap.setColor(Color.BLUE);
pixmap.fillCircle(dotX, dotY, 10);
}
}
// Store last position for next render() call
lastPos.set(newX, newY);
}
texture.draw(pixmap, 0, 0);
batch.begin();
batch.draw(texture, 0, 0);
batch.end();
}
}
Adecuate to your code as needed, I didn't know what was texture3 so I didn't include in my example
Also another option which I don't like too much because of rendering and storage cost is using a Polygon to draw the lines.
In LibGDX, I created a shader to do a transition effect where a circle forms over top of the image, where everything outside the circle is black, and everything inside the circle shows up as normal. This circle starts out big and shrinks to nothing. But I have a problem, as the circle is shrinking, it wobbles around. I also found I had this problem when using a ShadeRenderer to create a circle that also shrank over time, before using a shader. I think the problem as something to do with floating point numbers, or the way that circles are rendered. Anyway, I need to know, how do I fix it, so that I can get the circle to shrink smoothly?
Here is a gif demonstrating my problem of the wobbling circle (which I need to be smooth): my wobbling circle
Here is my Fragment Shader Code:
varying vec4 v_color;
varying vec3 v_position;
varying vec2 v_texCoord0;
uniform vec2 u_resolution;
uniform sampler2D u_sampler2D;
uniform float u_radius;
uniform int u_hasCircle;
void main() {
vec4 color = texture2D(u_sampler2D, v_texCoord0) * v_color;
vec2 relativePosition = gl_FragCoord.xy / u_resolution - .5;
relativePosition.x *= u_resolution.x / u_resolution.y;
float len = length(relativePosition);
if (u_hasCircle == 1 && len > u_radius) {
color = vec4(0, 0, 0, 1);
}
gl_FragColor = color;
}
And here is my vertex shader code that runs before that:
attribute vec4 a_color;
attribute vec3 a_position;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
uniform vec3 u_distort;
varying vec4 v_color;
varying vec3 v_position;
varying vec2 v_texCoord0;
void main() {
v_color = a_color;
v_position = a_position;
v_texCoord0 = a_texCoord0;
gl_Position = u_projTrans * vec4(a_position, 1.0);
}
When I want to transition to run, u_hasCircle is passed 1, otherwise it is passed 0. When the transition is running, I start with passing u_radius 1, and then I gradually decrease the value to 0, using a FloatAction in LibGDX.
I send these values to the shader once per frame.
Here is the relevant Libgdx Java code that interacts with the shader:
public class PlayWorld extends Group implements InputProcessor, Disposable
{
//various members
private PlayScreen screen;
private OrthographicCamera camera;
private FloatAction transitionToBattleAction;
private final float TRANS_TO_BATTLE_DURATION = 10f;
private float circleSize;
private boolean hasCircle = false;
public PlayWorld(PlayWorld playWorld) {
this.playWorld = playWorld;
camera = new OrthographicCamera();
tiledMap = new TiledMapActor(camera);
addActor(tiledMap);
transitionToBattleAction = new FloatAction();
}
//function that triggers transition
public void enterBattle() {
transitionToBattleAction.reset();
transitionToBattleAction.setStart(0);
transitionToBattleAction.setEnd(1);
transitionToBattleAction.setDuration(TRANS_TO_BATTLE_DURATION);
addAction();
}
// this function gets called every frame
#Override
public void act(float delta) {
super.act(delta);
if (transitionToBattleAction.getValue() == 0) {
//this function is defined in code shown below
tiledMap.unsetCircleSize();
} else if (transitionToBattleAction.getValue() < 1) {
//this function is defined in code shown below
tiledMap.setCircleSize(
1 - transitionToBattleAction.getValue());
} else if (transitionToBattleAction.getValue() == 1) {
//this function is defined in code shown below
tiledMap.setCircleSize(
1 - transitionToBattleAction.getValue());
transitionToBattleAction.restart();
screen.getGame().setScreen("battle");
} else if (transitionToBattleAction.getValue() > 1) {
//this function is defined in code shown below
tiledMap.unsetCircleSize();
transitionToBattleAction.restart();
}
}
//this gets called whenever the window resizes
public void resize(int width, int height) {
// this function is defined in code shown below
tiledMap.resize(width, height);
}
//various other methods
}
public class TiledMapActor extends Actor implements InputProcessor, Disposable
{
//various variables
private ShaderProgram shader;
private OrthographicCamera camera;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private float UNIT_SCALE = 1 / 16f;
public TiledMapActor(OrthographicCamera camera) {
super();
this.camera = camera;
map = new TmxMapLoader().load("myMap.tmx");
renderer = new OrthogonalTiledMapRenderer(map, UNIT_SCALE);
shader = new ShaderProgram(
Gdx.files.internal("shaders/myshader.vsh"),
Gdx.files.internal("shaders/myshader.fsh");
System.out.println(
shader.isCompiled() ?
"shader compiled" : shader.getLog());
renderer.getBatch().setShader(shader);
shader.begin();
shader.setUniformi("u_hasCircle", 0);
shader.end();
}
// this is called every time the window changes size
// from the PlayScreen class, see code above
public void resize(int width, int height) {
camera.viewportWidth = width;
camera.viewportHeight = height;
camera.update();
shader.begin();
shader.setUniformf("u_resolution", (float)width, (float)height);
shader.end();
}
//this method is called from code above, seen PlayScreen class code
//
public void setCircleSize(float circleSize) {
this.circleSize = circleSize;
hasCircle = true;
shader.begin();
shader.setUniformf("u_radius", circleSize);
shader.setUniformi("u_hasCircle", 1);
shader.end();
}
//this method is called from code above, seen PlayScreen class code
//
public void unsetCircleSize() {
hasCircle = false;
shader.begin();
shader.setUniformi("u_hasCircle", 0);
shader.end();
}
// Various other methods
}
So I found the problem, and stupid me! I was re-entering the transition scene every frame, once it started. I fixed it by using a boolean flag to tell me if the transition had started, and only starting the transition if that boolean flag wasn't set yet. Then later, at a point, after the transition had completed, I set that boolean flag back to false, so the transition could occur again!
I want to have a background texture with 3 rectangles and i want to create animation with them, - texture
But first rectangle cuts in a proper way and two others are cut in a dumb way
Proper way,
Dumb way #1,
Dumb way #2
Here is my code.
public class MainMenu implements Screen{
Texture background_main;
TextureRegion[] background_textures;
Animation background_animation;
SpriteBatch batch;
TextureRegion current_frame;
float stateTime;
BobDestroyer game;
OrthographicCamera camera;
public MainMenu(BobDestroyer game){
this.game = game;
}
#Override
public void show() {
camera = new OrthographicCamera();
camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch = new SpriteBatch();
background_main = new Texture(Gdx.files.internal("main_menu_screen/Background.png"));
background_textures = new TextureRegion[3];
for(int i = 0; i<3; i++){
background_textures[i] = new TextureRegion(background_main,0, 0+72*i, 128, 72+72*i);
}
background_animation = new Animation(2f,background_textures);
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
stateTime += Gdx.graphics.getDeltaTime();
current_frame = background_animation.getKeyFrame(stateTime, true);
batch.begin();
batch.draw(current_frame,0, 0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
batch.end();
}
}
If I understand you correctly, are you trying to create 3 TextureRegions of the same width/height? If yes, your issue may be with:
new TextureRegion(background_main,0, 0+72*i, 128, 72+72*i)
I think you'd want:
new TextureRegion(background_main,0, 0+72*i, 128, 72)
As the 128x72 is the width/height (not x/y positions) of your next TextureRegions, and do you not want them all the same height (72) as opposed to varying heights (72+72*i)?
I am very new to andEngine, I want to add sprites on screen and let them move and zoom on finger touch.
Right now i am able to add multiple sprites on scene , and they can be dragged on touch.
Here is my code:
public class Main extends SimpleBaseGameActivity {
#Override
private Camera camera;
private BitmapTextureAtlas mBitmapTextureAtlas;
private ITextureRegion mFaceTextureRegion;
private ITextureRegion mFaceTextureRegion2;
private static final int CAMERA_WIDTH = 800;
private static final int CAMERA_HEIGHT = 480;
#Override
public EngineOptions onCreateEngineOptions() {
camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
EngineOptions engineOptions = new EngineOptions(true,
ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(
CAMERA_WIDTH, CAMERA_HEIGHT), camera);
return engineOptions;
}
#Override
protected void onCreateResources() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.mBitmapTextureAtlas = new BitmapTextureAtlas(
this.getTextureManager(), 1024, 1600, TextureOptions.NEAREST);
// background
// this.background = new Sprite(0, 0,
// BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas,
// this, "ui_ball_1.png", 0, 0, 1, 1),
// this.getVertexBufferObjectManager());
this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mBitmapTextureAtlas, this,
"ui_ball_1.png", 0, 0);
this.mFaceTextureRegion2 = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mBitmapTextureAtlas, this,
"ui_ball_1.png", 0, 0);
this.mBitmapTextureAtlas.load();
// this.mEngine.getTextureManager().loadTexture(this.mBitmapTextureAtlas);
/*
* this.mBitmapTextureAtlas = new
* BitmapTextureAtlas(this.getTextureManager(), 32, 32,
* TextureOptions.BILINEAR); this.mFaceTextureRegion =
* BitmapTextureAtlasTextureRegionFactory
* .createFromAsset(this.mBitmapTextureAtlas, this, "ui_ball_1.png", 0,
* 0); this.mBitmapTextureAtlas.load();
*/
}
#Override
protected Scene onCreateScene() {
/*
* this.scene = new Scene(); this.scene.attachChild(this.background);
* this.scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));
* return this.scene;
*/
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene();
scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));
final float centerX = (CAMERA_WIDTH - this.mFaceTextureRegion
.getWidth()) / 2;
final float centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion
.getHeight()) / 2;
final Sprite face = new Sprite(centerX, centerY,
this.mFaceTextureRegion, this.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
return true;
}
};
face.setScale(2);
scene.attachChild(face);
scene.registerTouchArea(face);
final Sprite face2 = new Sprite(0, 0, this.mFaceTextureRegion2,
this.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
return true;
}
};
face2.setScale(2);
scene.attachChild(face2);
scene.registerTouchArea(face2);
scene.setTouchAreaBindingOnActionDownEnabled(true);
return scene;
}
}
Now i want to zoom each sprite on touch, but unable to find such method like setPosition available to move sprite to a specific position. Can anyone help me in achieving this without affecting the current functionality. Any help would be appreciated, may be in form of code or some direction/method to do this.
Thanks in advance :)
you can use a EntityModifier to make your effect:
#Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
this.clearEntityModifiers();
this.RegisterEntityModifier(new ScaleModifier(1f,2f,4f));
//1f = time to convert the scale of sprite of 2f to 4f
//2f = initial scale
//4f = finish scale
//when you dont touch the sprite back to normal scale
if(event.getAction()== MotionEvent.ACTION_UP) {
this.clearEntityModifiers();
this.RegisterEntityModifier(new ScaleModifier(1f,4f,2f));
}
//you also can work with "MotionEvent.ACTION_DOWN" and
//MotionEvent.ACTION_MOVE
return true;
}
Background information
I have just started learning HLSL and decided to test what I have learned from the Internet by writing a simple 2D XNA 4.0 bullet-hell game.
I have written a pixel shader in order to change the color of bullets.
Here is the idea: the original texture of the bullet is mainly black, white and red. With the help of my pixel shader, bullets can be much more colorful.
But, I'm not sure how and when the shader is applied on spriteBatch in XNA 4.0, and when it ends. This may be the cause of problem.
There were pass.begin() and pass.end() in XNA 3.x, but pass.apply() in XNA 4.0 confuses me.
In addition, it is the first time for me to use renderTarget. It may cause problems.
Symptom
It works, but only if there are bullets of the same color in the bullet list.
If bullets of different colors are rendered, it produces wrong colors.
It seems that the pixel shader is not applied on the bullet texture, but applied on the renderTarget, which contains all the rendered bullets.
For an example:
Here I have some red bullets and blue bullets. The last created bullet is a blue one. It seems that the pixel shader have added blue color on the red ones, making them to be blue-violet.
If I continuously create bullets, the red bullets will appear to be switching between red and blue-violet. (I believe that the blue ones are also switching, but not obvious.)
Code
Since I am new to HLSL, I don't really know what I have to provide.
Here are all the things that I believe or don't know if they are related to the problem.
C# - Enemy bullet (or just Bullet):
protected SpriteBatch spriteBatch;
protected Texture2D texture;
protected Effect colorEffect;
protected Color bulletColor;
... // And some unrelated variables
public EnemyBullet(SpriteBatch spriteBatch, Texture2D texture, Effect colorEffect, BulletType bulletType, (and other data, like velocity)
{
this.spriteBatch = spriteBatch;
this.texture = texture;
this.colorEffect = colorEffect;
if(bulletType == BulletType.ARROW_S)
{
bulletColor = Color.Red; // The bullet will be either red
}
else
{
bulletColor = Color.Blue; // or blue.
}
}
public void Update()
{
... // Update positions and other properties, but not the color.
}
public void Draw()
{
colorEffect.Parameters["DestColor"].SetValue(bulletColor.ToVector4());
int l = colorEffect.CurrentTechnique.Passes.Count();
for (int i = 0; i < l; i++)
{
colorEffect.CurrentTechnique.Passes[i].Apply();
spriteBatch.Draw(texture, Position, sourceRectangle, Color.White, (float)Math.PI - rotation_randian, origin, Scale, SpriteEffects.None, 0.0f);
}
}
C# - Bullet manager:
private Texture2D bulletTexture;
private List<EnemyBullet> enemyBullets;
private const int ENEMY_BULLET_CAPACITY = 10000;
private RenderTarget2D bulletsRenderTarget;
private Effect colorEffect;
...
public EnemyBulletManager()
{
enemyBullets = new List<EnemyBullet>(ENEMY_BULLET_CAPACITY);
}
public void LoadContent(ContentManager content, SpriteBatch spriteBatch)
{
bulletTexture = content.Load<Texture2D>(#"Textures\arrow_red2");
bulletsRenderTarget = new RenderTarget2D(spriteBatch.GraphicsDevice, spriteBatch.GraphicsDevice.PresentationParameters.BackBufferWidth, spriteBatch.GraphicsDevice.PresentationParameters.BackBufferHeight, false, SurfaceFormat.Color, DepthFormat.None);
colorEffect = content.Load<Effect>(#"Effects\ColorTransform");
colorEffect.Parameters["ColorMap"].SetValue(bulletTexture);
}
public void Update()
{
int l = enemyBullets.Count();
for (int i = 0; i < l; i++)
{
if (enemyBullets[i].IsAlive)
{
enemyBullets[i].Update();
}
else
{
enemyBullets.RemoveAt(i);
i--;
l--;
}
}
}
// This function is called before Draw()
public void PreDraw()
{
// spriteBatch.Begin() is called outside this class, for reference:
// spriteBatch.Begin(SpriteSortMode.Immediate, null);
spriteBatch.GraphicsDevice.SetRenderTarget(bulletsRenderTarget);
spriteBatch.GraphicsDevice.Clear(Color.Transparent);
int l = enemyBullets.Count();
for (int i = 0; i < l; i++)
{
if (enemyBullets[i].IsAlive)
{
enemyBullets[i].Draw();
}
}
spriteBatch.GraphicsDevice.SetRenderTarget(null);
}
public void Draw()
{
// Before this function is called,
// GraphicsDevice.Clear(Color.Black);
// is called outside.
spriteBatch.Draw(bulletsRenderTarget, Vector2.Zero, Color.White);
// spriteBatch.End();
}
// This function will be responsible for creating new bullets.
public EnemyBullet CreateBullet(EnemyBullet.BulletType bulletType, ...)
{
EnemyBullet eb = new EnemyBullet(spriteBatch, bulletTexture, colorEffect, bulletType, ...);
enemyBullets.Add(eb);
return eb;
}
HLSL - Effects\ColorTransform.fx
float4 DestColor;
texture2D ColorMap;
sampler2D ColorMapSampler = sampler_state
{
Texture = <ColorMap>;
};
struct PixelShaderInput
{
float2 TexCoord : TEXCOORD0;
};
float4 PixelShaderFunction(PixelShaderInput input) : COLOR0
{
float4 srcRGBA = tex2D(ColorMapSampler, input.TexCoord);
float fmax = max(srcRGBA.r, max(srcRGBA.g, srcRGBA.b));
float fmin = min(srcRGBA.r, min(srcRGBA.g, srcRGBA.b));
float delta = fmax - fmin;
float4 originalDestColor = float4(1, 0, 0, 1);
float4 deltaDestColor = originalDestColor - DestColor;
float4 finalRGBA = srcRGBA - (deltaDestColor * delta);
return finalRGBA;
}
technique Technique1
{
pass ColorTransform
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
I would be appreciate if anyone can help solving the problem. (Or optimizing my shader. I really know very little about HLSL.)
In XNA 4 you should pass the effect directly to the SpriteBatch, as explained on Shawn Hargreaves' Blog.
That said, it seems to me like the problem is, that after rendering your bullets to bulletsRenderTarget, you then draw that RenderTarget using the same spriteBatch with the last effect still in action. That would explain why the entire image is painted blue.
A solution would be to use two Begin()/End() passes of SpriteBatch, one with the effect and the other without. Or just don't use a separate RenderTarget to begin with, which seems pointless in this case.
I'm also very much a beginner with pixel shaders so, just my 2c.